├── .babelrc ├── .editorconfig ├── .github └── workflows │ └── nodejs.yml ├── .gitignore ├── .prettierrc ├── LICENSE ├── README.md ├── __tests__ └── libs │ ├── abstraction │ └── abstractor.basic.test.ts │ ├── complexity │ ├── modularizer.basic.test.ts │ ├── modularizer.complex.test.ts │ ├── nonsortal_line.test.ts │ ├── relator_chain.test.ts │ ├── viewpoint_extractor.kindview.test.ts │ ├── viewpoint_extractor.nonsortalview.test.ts │ ├── viewpoint_extractor.phaseview.test.ts │ ├── viewpoint_extractor.relatorview.test.ts │ ├── viewpoint_extractor.roleview.test.ts │ └── viewpoint_extractor.subkindview.test.ts │ ├── ontouml │ ├── cardinality.test.ts │ ├── class.ancestors.test.ts │ ├── class.descendents.test.ts │ ├── class.generalization.test.ts │ ├── class.nature.test.ts │ ├── class.serialization.test.ts │ ├── class.stereotype.test.ts │ ├── class.test.ts │ ├── classifier.test.ts │ ├── container.test.ts │ ├── decoratable.test.ts │ ├── generalization.test.ts │ ├── generalization_set.test.ts │ ├── howto.test.ts │ ├── literal.test.ts │ ├── multilingual_text.test.ts │ ├── natures.test.ts │ ├── package.factory.test.ts │ ├── package.test.ts │ ├── project.test.ts │ ├── property.test.ts │ ├── relation.ancestors.test.ts │ ├── relation.descendents.test.ts │ ├── relation.serialization.test.ts │ ├── relation.stereotype.test.ts │ ├── relation.test.ts │ ├── schema.test.ts │ ├── serialization.test.ts │ ├── stereotypes.test.ts │ └── utils.test.ts │ ├── ontouml2db │ ├── general.test.ts │ ├── generateOntopFiles.test.ts │ ├── mapperOTpC.test.ts │ ├── mapperOTpCC.test.ts │ ├── mapperOTpK.test.ts │ └── test_resources │ │ ├── 001_simple_flattening.ts │ │ ├── 002_flatting_with_duplicate_attributes.ts │ │ ├── 003_flatting_gs.ts │ │ ├── 004_flatting_multiples_generalizations.ts │ │ ├── 005_flatting_orthogonal_gs.ts │ │ ├── 006_flatting_cascading_gs.ts │ │ ├── 007_flatting_category_without_specialization.ts │ │ ├── 008_flatting_root_association.ts │ │ ├── 009_flatting_with_association.ts │ │ ├── 010_flatting_with_association_multiples_generalizations.ts │ │ ├── 011_flatting_cascading_association_multiples_gs.ts │ │ ├── 012_simple_lifting.ts │ │ ├── 013_lifting_cascade_generalization.ts │ │ ├── 014_lifting_multiple_generalizations.ts │ │ ├── 015_lifting_multiple_generalizations_duplicate_attributes.ts │ │ ├── 016_lifting_cascade_generalization_association.ts │ │ ├── 017_lifting_gs_association.ts │ │ ├── 018_lifting_orthogonal_gs.ts │ │ ├── 019_lifting_generalization_and_gs.ts │ │ ├── 020_lifting_hierarchy_gs.ts │ │ ├── 021_lifting_generalization_and_gs_association.ts │ │ ├── 022_lifting_gs_disjoint_complete.ts │ │ ├── 023_lifting_gs_disjoint_incomplete.ts │ │ ├── 024_lifting_gs_overlapping_complete.ts │ │ ├── 025_lifting_gs_overlapping_incomplete.ts │ │ ├── 026_flatting_to_class_association.ts │ │ ├── 027_lifting_multiple_relations_to_remake.ts │ │ ├── 028_multivalued_property.ts │ │ ├── 029_h2_script.ts │ │ ├── 030_mysql_script.ts │ │ ├── 031_oracle_script.ts │ │ ├── 032_postgre.script.ts │ │ ├── 033_sqlserver_script.ts │ │ ├── 034_lifting_with_duplicate_attributes.ts │ │ ├── 035_enum_field_to_lookup_table.ts │ │ ├── 036_enum_field_to_lookup_tables_h2.ts │ │ ├── 037_test_generic_db_without_lookup_tabele_for_enums.ts │ │ ├── TestResource.ts │ │ ├── baseExample.ts │ │ └── graph_tester │ │ ├── GraphChecker.ts │ │ ├── NodeChecker.ts │ │ ├── OntoUML2DBOptions_TO_BE_DELETED.ts │ │ ├── PropertyChecker.ts │ │ ├── RelationshipChecker.ts │ │ ├── ScriptChecker.ts │ │ ├── TrackerChecker.ts │ │ └── functions.ts │ ├── ontouml2gufo │ ├── attributes.test.ts │ ├── cardinalities.test.ts │ ├── classes.test.ts │ ├── custom_element_mapping.test.ts │ ├── description.test.ts │ ├── enumeration.test.ts │ ├── generalization_set.test.ts │ ├── generalizations.test.ts │ ├── helpers.ts │ ├── inspector.test.ts │ ├── names.test.ts │ ├── relations.test.ts │ ├── relations_inverse.test.ts │ ├── subpackages.test.ts │ ├── uri_generation.test.ts │ ├── uri_generation_duplicates.test.ts │ └── uri_name_normalization.test.ts │ ├── ontouml2owl │ ├── class_views.test.ts │ ├── classes.test.ts │ ├── diagrams.test.ts │ ├── generalization_sets.test.ts │ ├── generalizations.test.ts │ ├── helpers.ts │ ├── literals.test.ts │ ├── packages.test.ts │ ├── path.test.ts │ ├── project.test.ts │ ├── properties.test.ts │ ├── rectangle.test.ts │ ├── relation_views.test.ts │ ├── relations.test.ts │ ├── special_characters.test.ts │ └── stereotypes.test.ts │ └── verification │ ├── class_verification.test.ts │ ├── generalization_verification.test.ts │ └── ontouml2verification.test.ts ├── index.ts ├── jest.config.js ├── package-lock.json ├── package.json ├── resources ├── howto.png ├── schema.json └── schemas │ ├── class.schema.json │ ├── class_view.schema.json │ ├── definitions.schema.json │ ├── diagram.schema.json │ ├── generalization.schema.json │ ├── generalization_set.schema.json │ ├── generalization_set_view.schema.json │ ├── generalization_view.schema.json │ ├── literal.schema.json │ ├── package.schema.json │ ├── package_view.schema.json │ ├── path_shape.schema.json │ ├── project.schema.json │ ├── property.schema.json │ ├── rectangle_shape.schema.json │ ├── relation.schema.json │ ├── relation_view.schema.json │ └── text_shape.schema.json ├── setup.ts ├── src ├── index.ts └── libs │ ├── abstraction │ ├── abstraction.ts │ ├── abstractor.ts │ └── index.ts │ ├── complexity │ ├── index.ts │ ├── modularizer.ts │ ├── module.ts │ └── viewpoint_extractor.ts │ ├── index.ts │ ├── ontouml │ ├── container_utils.ts │ ├── index.ts │ ├── model │ │ ├── cardinality.ts │ │ ├── class.ts │ │ ├── classifier.ts │ │ ├── decoratable.ts │ │ ├── generalization.ts │ │ ├── generalization_set.ts │ │ ├── literal.ts │ │ ├── model_element.ts │ │ ├── model_element_container.ts │ │ ├── natures.ts │ │ ├── package.ts │ │ ├── property.ts │ │ ├── relation.ts │ │ └── stereotypes.ts │ ├── multilingual_text.ts │ ├── ontouml_element.ts │ ├── ontouml_type.ts │ ├── project.ts │ ├── schema.json │ ├── serialization.ts │ ├── utils.ts │ └── view │ │ ├── class_view.ts │ │ ├── connector_view.ts │ │ ├── diagram.ts │ │ ├── diagram_element.ts │ │ ├── element_view.ts │ │ ├── generalization_set_view.ts │ │ ├── generalization_view.ts │ │ ├── node_view.ts │ │ ├── package_view.ts │ │ ├── path.ts │ │ ├── point.ts │ │ ├── rectangle.ts │ │ ├── rectangular_shape.ts │ │ ├── relation_view.ts │ │ ├── shape.ts │ │ └── text.ts │ ├── ontouml2db │ ├── Ontouml2Db.ts │ ├── Ontouml2DbOptions.ts │ ├── approaches │ │ ├── IStrategy.ts │ │ ├── one_table_per_class │ │ │ └── OneTablePerClass.ts │ │ ├── one_table_per_concrete_class │ │ │ └── OneTablePerConcreteClass.ts │ │ ├── one_table_per_kind │ │ │ └── OneTablePerKind.ts │ │ └── processes │ │ │ ├── Flatten.ts │ │ │ └── Lifting.ts │ ├── constants │ │ ├── DbmsSupported.ts │ │ ├── StrategyType.ts │ │ └── enumerations.ts │ ├── convert │ │ ├── SolvesCardinalityNtoN.ts │ │ ├── SolvesEnumeration.ts │ │ ├── SolvesForeignKey.ts │ │ ├── SolvesMultivaluedProperty.ts │ │ ├── SolvesName.ts │ │ ├── SolvesPrimaryKey.ts │ │ ├── ToEntityRelationship.ts │ │ └── ToRelationalSchema.ts │ ├── factory │ │ └── Factory.ts │ ├── graph │ │ ├── AssociationContainer.ts │ │ ├── AssociationContainerInterface.ts │ │ ├── Graph.ts │ │ ├── GraphAssociation.ts │ │ ├── GraphGeneralization.ts │ │ ├── GraphGeneralizationSet.ts │ │ ├── GraphRelation.ts │ │ ├── Node.ts │ │ ├── NodeProperty.ts │ │ ├── NodePropertyEnumeration.ts │ │ ├── PropertyContainer.ts │ │ └── PropertyContainerInterface.ts │ ├── index.ts │ ├── obda │ │ ├── GenerateConnection.ts │ │ ├── GenerateObda.ts │ │ ├── GenerateObdaMappingId.ts │ │ ├── GenerateObdaSource.ts │ │ └── GenerateObdaTarget.ts │ ├── supported_database │ │ ├── DbmsInterface.ts │ │ ├── Generic.ts │ │ ├── H2.ts │ │ ├── MySql.ts │ │ ├── Oracle.ts │ │ ├── Postgre.ts │ │ └── SqlServer.ts │ ├── tracker │ │ ├── Filter.ts │ │ ├── TracedNode.ts │ │ ├── Tracer.ts │ │ └── Tracker.ts │ └── util │ │ ├── Increment.ts │ │ └── Util.ts │ ├── ontouml2gufo │ ├── annotation_function.ts │ ├── attribute_functions.ts │ ├── cardinality_functions.ts │ ├── class_functions.ts │ ├── generalization_functions.ts │ ├── generalization_set_functions.ts │ ├── index.ts │ ├── inspector.ts │ ├── issue.ts │ ├── ontouml2gufo.ts │ ├── options.ts │ ├── prefix_functions.ts │ ├── relation_functions.ts │ ├── relations_inverse_functions.ts │ └── uri_manager.ts │ ├── ontouml2owl │ ├── index.ts │ └── ontouml2owl.ts │ ├── service.ts │ ├── service_issue.ts │ ├── service_issue_severity.ts │ ├── service_options.ts │ └── verification │ ├── class_verification.ts │ ├── constants.ts │ ├── generalization_set_verification.ts │ ├── generalization_verification.ts │ ├── index.ts │ ├── literal_verification.ts │ ├── ontouml_verification.ts │ ├── package_verification.ts │ ├── project_verification.ts │ ├── property_verification.ts │ ├── relation_verification.ts │ ├── utils.ts │ └── verification_issue.ts ├── tsconfig.json ├── tsconfig.release.json ├── tslint.json └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { "targets": { "node": "current" } } 6 | ], 7 | "@babel/preset-typescript"], 8 | "plugins": [ 9 | "@babel/plugin-transform-runtime", 10 | "@babel/plugin-proposal-class-properties", 11 | "@babel/plugin-proposal-optional-chaining", 12 | [ 13 | "module-resolver", { 14 | "alias": { 15 | "@test-models": "./__tests__/test_models", 16 | "@constants": "./src/constants", 17 | "@error": "./src/error", 18 | "@libs": "./src/libs", 19 | "@rules": "./src/rules", 20 | "@utils": "./src/utils", 21 | "@resources": "./resources" 22 | } 23 | } 24 | ] 25 | ] 26 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | 9 | [*.md] 10 | insert_final_newline = false 11 | trim_trailing_whitespace = false 12 | 13 | [*.{js,jsx,json,ts,tsx,yml}] 14 | indent_size = 2 15 | indent_style = space 16 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | 2 | on: [pull_request] 3 | 4 | jobs: 5 | build: 6 | 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | matrix: 11 | node-version: [14.x] 12 | 13 | steps: 14 | - uses: actions/checkout@v1 15 | - name: Use Node.js ${{ matrix.node-version }} 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: ${{ matrix.node-version }} 19 | - name: npm install, build, and test 20 | run: | 21 | npm ci 22 | npm run build --if-present 23 | npm test 24 | env: 25 | CI: true 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Dependencies 7 | node_modules/ 8 | 9 | # Coverage 10 | coverage 11 | 12 | # Transpiled files 13 | dist/ 14 | bundle/ 15 | 16 | # VS Code 17 | .vscode 18 | !.vscode/tasks.js 19 | 20 | # JetBrains IDEs 21 | .idea/ 22 | 23 | # Env 24 | .env 25 | 26 | # Optional npm cache directory 27 | .npm 28 | 29 | # Optional eslint cache 30 | .eslintcache 31 | 32 | # Misc 33 | .DS_Store 34 | catalog-v001.xml 35 | 36 | # Ontology output test files 37 | *.ttl 38 | *.n3 39 | *.nt 40 | __tests__/libs/ontouml2gufo/examples/* 41 | 42 | # Manually exported packages 43 | ontouml-js-*.tgz 44 | 45 | # Ignore TSDoc output 46 | tsdoc/ 47 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "none", 4 | "arrowParens": "avoid", 5 | "printWidth": 130, 6 | "overrides": [ 7 | { 8 | "files": "*.ts", 9 | "options": { 10 | "parser": "typescript", 11 | "printWidth": 130 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OntoUML JS 2 | 3 | ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/OntoUML/ontouml-js/Node%20CI?style=flat-square) 4 | 5 | Javascript library utility for manipulating OntoUML models. 6 | 7 | ## Getting Start 8 | 9 | ``` 10 | npm install ontouml-js --save 11 | 12 | // yarn users 13 | yarn add ontouml-js 14 | ``` 15 | 16 | ## Usage 17 | 18 | This package is designed to support manipulating OntoUML models and their serialization into [`ontouml-schema`](https://github.com/OntoUML/ontouml-schema) compliant JSON files. 19 | 20 | ```javascript 21 | import { Project, serializationUtils } from 'ontouml-js'; 22 | 23 | // Every OntoUML element can be created from a constructor that can receive a partial object as references for its creation 24 | const project = new Project({ name: 'My Project' }); // creates an OntoUML projects 25 | 26 | // Projects contain an instance of Package dubbed model that contains all model elements in the project 27 | // Container elements, e.g., projects and packages, also serve as factories for their contents 28 | const model = project.createModel({ name: 'Model a.k.a. Root Package' }); // creates a "model" Package 29 | 30 | // Instead of partial objects, "factory" methods receive more suitable lists of arguments to facilitating populating elements 31 | const person = model.createKind('Person'); 32 | const school = model.createKind('School'); 33 | const date = model.createDatatype('Date'); 34 | const enrollment = model.createRelator('Enrollment'); 35 | const studiesAt = model.createMaterialRelation(person, school, 'studies at'); 36 | 37 | model.createMediationRelation(enrollment, person); 38 | model.createMediationRelation(enrollment, school); 39 | 40 | // our API is constantly updated to include helpful methods to facilitate building OntoUML models 41 | studiesAt.getTargetEnd().name = 'school'; 42 | studiesAt.getTargetEnd().setCardinalityToMany(); 43 | studiesAt.getSourceEnd().name = 'student'; 44 | studiesAt.getSourceEnd().cardinality = '1..*'; 45 | 46 | enrollment.createAttribute(date, 'enrollment date'); 47 | 48 | // Containers also include methods to easily support retrieving their contents 49 | model.getAllAttributes(); // returns all contained attributes 50 | model.getAllClasses(); // returns all contained classes 51 | model.getAllGeneralizations(); // returns all contained generalizations 52 | 53 | // Any element can be easily serialized into JSON, and properly serialized elements can be deserialized just as easily 54 | const projectSerialization = JSON.stringify(project); 55 | const projectCopy = serializationUtils.parse(projectSerialization); 56 | ``` 57 | 58 | ## About 59 | 60 | If you are interested to know more, feel free to open an issue to provide feedback on the project or reach our team members for more specific cases: 61 | * [Claudenir M. Fonseca](https://github.com/claudenirmf) 62 | * [Tiago Prince Sales](https://github.com/tgoprince) 63 | * [Lucas Bassetti](https://github.com/LucasBassetti) 64 | * [Victor Viola](https://github.com/victorviola) 65 | 66 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml/class.serialization.test.ts: -------------------------------------------------------------------------------- 1 | import { ClassStereotype, OntologicalNature, ORDERLESS_LEVEL, Package, Project, serializationUtils } from '@libs/ontouml'; 2 | 3 | describe('Test Class serialization', () => { 4 | let project: Project; 5 | let model: Package; 6 | 7 | beforeEach(() => { 8 | project = new Project(); 9 | model = project.createModel(); 10 | }); 11 | 12 | it('Test empty class serialization', () => { 13 | const emptyClass = model.createClass(); 14 | const serialization = emptyClass.toJSON(); 15 | 16 | expect(serialization.stereotype).toEqual(null); 17 | expect(serialization.restrictedTo).toEqual(null); 18 | expect(serialization.properties).toEqual(null); 19 | expect(serialization.literals).toEqual(null); 20 | expect(serialization.isAbstract).toEqual(false); 21 | expect(serialization.isDerived).toEqual(false); 22 | expect(serialization.isExtensional).toEqual(false); 23 | expect(serialization.isPowertype).toEqual(false); 24 | expect(serialization.order).toEqual('1'); 25 | }); 26 | 27 | it('Test fully featured category serialization', () => { 28 | const fullyFeaturedCategory = model.createCategory('category', OntologicalNature.functional_complex, { 29 | isAbstract: true, 30 | isDerived: true, 31 | isExtensional: true, 32 | isPowertype: true, 33 | order: ORDERLESS_LEVEL 34 | }); 35 | const enumeration = model.createEnumeration(); 36 | const attribute = fullyFeaturedCategory.createAttribute(enumeration); 37 | const serialization = fullyFeaturedCategory.toJSON(); 38 | 39 | expect(serialization.stereotype).toContain(ClassStereotype.CATEGORY); 40 | expect(serialization.restrictedTo).toContain(OntologicalNature.functional_complex); 41 | expect(serialization.properties).toContain(attribute); 42 | expect(serialization.literals).toEqual(null); 43 | expect(serialization.isAbstract).toEqual(true); 44 | expect(serialization.isDerived).toEqual(true); 45 | expect(serialization.isExtensional).toEqual(true); 46 | expect(serialization.isPowertype).toEqual(true); 47 | expect(serialization.order).toEqual('*'); 48 | }); 49 | 50 | it('Test enumeration serialization', () => { 51 | const enumeration = model.createEnumeration(); 52 | const literal = enumeration.createLiteral(); 53 | const serialization = enumeration.toJSON(); 54 | 55 | expect(serialization.stereotype).toContain(ClassStereotype.ENUMERATION); 56 | expect(serialization.restrictedTo).toContain(OntologicalNature.abstract); 57 | expect(serialization.properties).toEqual(null); 58 | expect(serialization.literals).toContain(literal); 59 | }); 60 | 61 | it('Test classes serialization within project', () => { 62 | expect(() => JSON.stringify(project)).not.toThrow(); 63 | }); 64 | 65 | it('Test classes validation within project', async () => { 66 | const isValid = await serializationUtils.validate(project); 67 | 68 | if (isValid !== true) { 69 | console.log('Project serialization is not valid', isValid); 70 | console.log(JSON.stringify(project, null, 2)); 71 | } 72 | 73 | expect(isValid).toEqual(true); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml/decoratable.test.ts: -------------------------------------------------------------------------------- 1 | import { Class, Relation, Property, ClassStereotype, PropertyStereotype, RelationStereotype } from '@libs/ontouml'; 2 | 3 | describe('Decoratable Interface Tests', () => { 4 | it('Class with no stereotypes', () => { 5 | const _class = new Class(); 6 | expect(_class.stereotype).toBeNull(); 7 | expect(_class.isStereotypeValid()).not.toBeTruthy(); 8 | }); 9 | 10 | it('Class with single stereotype', () => { 11 | // Invalid stereotype 12 | const _class = new Class({ stereotype: 'asd' as ClassStereotype }); 13 | expect(_class.stereotype).toEqual('asd'); 14 | expect(_class.isStereotypeValid()).not.toBeTruthy(); 15 | 16 | // Valid stereotype 17 | _class.stereotype = ClassStereotype.KIND; 18 | expect(_class.stereotype).toEqual(ClassStereotype.KIND); 19 | expect(_class.isStereotypeValid()).toBeTruthy(); 20 | }); 21 | 22 | it('Relation with no stereotypes', () => { 23 | const relation = new Relation(); 24 | expect(relation.stereotype).toBeNull(); 25 | expect(relation.isStereotypeValid()).toBeTruthy(); 26 | }); 27 | 28 | it('Relation with single stereotype', () => { 29 | // Invalid stereotype 30 | const relation = new Relation({ stereotype: 'asd' as RelationStereotype }); 31 | expect(relation.stereotype).toEqual('asd'); 32 | expect(relation.isStereotypeValid()).not.toBeTruthy(); 33 | 34 | // Valid stereotype 35 | relation.stereotype = RelationStereotype.MATERIAL; 36 | expect(relation.stereotype).toEqual(RelationStereotype.MATERIAL); 37 | expect(relation.isStereotypeValid()).toBeTruthy(); 38 | }); 39 | 40 | it('Property with no stereotypes', () => { 41 | const property = new Property(); 42 | expect(property.stereotype).toBeNull(); 43 | expect(property.isStereotypeValid()).toBeTruthy(); 44 | }); 45 | 46 | it('Property with single stereotype', () => { 47 | // Invalid stereotype 48 | const property = new Property({ stereotype: 'asd' as PropertyStereotype }); 49 | expect(property.stereotype).toEqual('asd'); 50 | expect(property.isStereotypeValid()).not.toBeTruthy(); 51 | 52 | // Valid stereotype 53 | property.stereotype = PropertyStereotype.BEGIN; 54 | expect(property.stereotype).toEqual(PropertyStereotype.BEGIN); 55 | expect(property.isStereotypeValid()).toBeTruthy(); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml/howto.test.ts: -------------------------------------------------------------------------------- 1 | import { Project, serializationUtils } from '@libs/ontouml'; 2 | 3 | it('Test the example presented in the "Usage" section of the README file', () => 4 | expect(() => { 5 | // Every OntoUML element can be created from a constructor that can receive a partial object as references for its creation 6 | const project = new Project(); // creates an OntoUML project 7 | project.addName('My Project'); 8 | 9 | // Projects contain an instance of Package dubbed model that contains all model elements in the project 10 | // Container elements, e.g., projects and packages, also serve as factories for their contents 11 | const model = project.createModel(); // creates a "model" Package 12 | model.addName('Model a.k.a. Root Package'); 13 | 14 | // Instead of partial objects, "factory" methods receive more suitable lists of arguments to facilitating populating elements 15 | const person = model.createKind('Person'); 16 | const school = model.createKind('School'); 17 | const date = model.createDatatype('Date'); 18 | const enrollment = model.createRelator('Enrollment'); 19 | const studiesAt = model.createMaterialRelation(person, school, 'studies at'); 20 | 21 | model.createMediationRelation(enrollment, person); 22 | model.createMediationRelation(enrollment, school); 23 | 24 | // the API is constantly updated to include helpful methods to facilitate building OntoUML models 25 | studiesAt.getTargetEnd().addName('school'); 26 | studiesAt.getTargetEnd().cardinality.setZeroToMany(); 27 | studiesAt.getSourceEnd().addName('student'); 28 | studiesAt.getSourceEnd().cardinality.setOneToMany(); 29 | 30 | enrollment.createAttribute(date, 'enrollment date'); 31 | 32 | // Containers also include methods to easily support retrieving their contents 33 | model.getAllAttributes(); // returns all contained attributes 34 | model.getAllClasses(); // returns all contained classes 35 | model.getAllGeneralizations(); // returns all contained generalizations 36 | 37 | // Any element can be easily serialized into JSON, and properly serialized elements can be deserialized just as easily 38 | const projectSerialization = JSON.stringify(project); 39 | const projectCopy = serializationUtils.parse(projectSerialization); 40 | }).not.toThrow()); 41 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml/literal.test.ts: -------------------------------------------------------------------------------- 1 | import { Literal, Project, serializationUtils } from '@libs/ontouml'; 2 | 3 | describe(`${Literal.name} Tests`, () => { 4 | describe(`Test ${Literal.prototype.toJSON.name}()`, () => { 5 | const model = new Project().createModel(); 6 | const gameStatus = model.createEnumeration(); 7 | const started = gameStatus.createLiteral(); 8 | gameStatus.createLiteral(); 9 | gameStatus.createLiteral(); 10 | 11 | it('Test serialization', () => expect(() => JSON.stringify(started)).not.toThrow()); 12 | it('Test serialization validation', () => expect(serializationUtils.validate(started.project)).toBe(true)); 13 | }); 14 | 15 | describe(`Test ${Literal.prototype.setContainer.name}()`, () => { 16 | const model = new Project().createModel(); 17 | const _enum = model.createClass(); 18 | const lit = new Literal({ project: model.project }); 19 | 20 | it('Test function call', () => { 21 | expect(lit.container).not.toBe(_enum); 22 | expect(_enum.literals).toHaveLength(0); 23 | 24 | _enum.addLiteral(lit); 25 | 26 | expect(lit.container).toBe(_enum); 27 | expect(lit.project).toBe(_enum.project); 28 | expect(_enum.literals).toContain(lit); 29 | }); 30 | }); 31 | 32 | describe(`Test ${Literal.prototype.clone.name}()`, () => { 33 | const model = new Project().createModel(); 34 | const classA = model.createEnumeration(); 35 | const litA = classA.createLiteral(); 36 | const litB = litA.clone(); 37 | 38 | const litC = new Literal(); 39 | const litD = litC.clone(); 40 | 41 | it('Test method', () => expect(litA).toEqual(litB)); 42 | it('Test method', () => expect(litC).toEqual(litD)); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml/multilingual_text.test.ts: -------------------------------------------------------------------------------- 1 | import { MultilingualText, Project } from '@libs/ontouml'; 2 | 3 | describe('MultilingualText Tests', () => { 4 | let text: MultilingualText; 5 | 6 | beforeEach(() => { 7 | text = new MultilingualText(); 8 | }); 9 | 10 | // person.addName('Person'); 11 | // organization.name.addAll({ en: 'Organization', 'en-US': 'Private Organization', 'pt-BR': 'Organização' }); 12 | // product.name.addAll({ 'en-US': 'Product', 'pt-BR': 'Produto' }); 13 | 14 | it('Test null/undefined text', () => { 15 | expect(text.getText()).toBe(null); 16 | }); 17 | 18 | it('Test string text', () => { 19 | text.addText('Pessoa', 'pt'); 20 | expect(text.getText('pt')).toBe('Pessoa'); 21 | }); 22 | 23 | it('Test get default language', () => { 24 | text.addText('Person'); 25 | expect(text.getText()).toBe('Person'); 26 | }); 27 | 28 | it('Test get specific language if possible', () => { 29 | text.addText('Person', 'en'); 30 | text.addText('Pessoa', 'pt'); 31 | expect(text.getText()).toBe('Person'); 32 | 33 | MultilingualText.languagePreference = ['pt', 'en']; 34 | expect(text.getText()).toBe('Pessoa'); 35 | }); 36 | 37 | it("Test add text using invalid tag fallbacks to default language ('en')", () => { 38 | expect(() => text.addText('Person', 'xx')).not.toThrow(); 39 | expect(text.getText()).toBe('Person'); 40 | }); 41 | 42 | it("Test get text using invalid tag fallbacks to default language ('en')", () => { 43 | let value; 44 | text.addText('Person', 'en'); 45 | expect(() => (value = text.getText('xx'))).not.toThrow(); 46 | expect(value).toBe('Person'); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml/relation.ancestors.test.ts: -------------------------------------------------------------------------------- 1 | import { Project, Relation } from '@libs/ontouml'; 2 | 3 | describe('Relation: test ancestor-related query methods', () => { 4 | const model = new Project().createModel(); 5 | const person = model.createClass(); 6 | const knows = model.createBinaryRelation(person, person); 7 | const isFriendsWith = model.createBinaryRelation(person, person); 8 | const isBestFriendsWith = model.createBinaryRelation(person, person); 9 | model.createGeneralization(knows, isFriendsWith); 10 | model.createGeneralization(isFriendsWith, isBestFriendsWith); 11 | 12 | describe('Test getParents()', () => { 13 | it('Test function call', () => expect(isBestFriendsWith.getParents()).toContain(isFriendsWith)); 14 | it('Test function call', () => expect(isBestFriendsWith.getParents().length).toBe(1)); 15 | }); 16 | 17 | describe('Test getAncestors()', () => { 18 | it('Test function call', () => expect(isBestFriendsWith.getAncestors()).toContain(isFriendsWith)); 19 | it('Test function call', () => expect(isBestFriendsWith.getAncestors()).toContain(knows)); 20 | it('Test function call', () => expect(isBestFriendsWith.getAncestors().length).toBe(2)); 21 | }); 22 | 23 | describe('Test getFilteredAncestors()', () => { 24 | const filter = (ancestor: Relation) => ancestor === knows; 25 | 26 | it('Test function call', () => expect(isBestFriendsWith.getFilteredAncestors(filter)).toContain(knows)); 27 | it('Test function call', () => expect(isBestFriendsWith.getFilteredAncestors(filter).length).toBe(1)); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml/relation.descendents.test.ts: -------------------------------------------------------------------------------- 1 | import { Project, Relation } from '@libs/ontouml'; 2 | 3 | describe('Relation: test ancestor-related query methods', () => { 4 | const model = new Project().createModel(); 5 | const person = model.createClass(); 6 | const knows = model.createBinaryRelation(person, person); 7 | const isFriendsWith = model.createBinaryRelation(person, person); 8 | const isBestFriendsWith = model.createBinaryRelation(person, person); 9 | model.createGeneralization(knows, isFriendsWith); 10 | model.createGeneralization(isFriendsWith, isBestFriendsWith); 11 | 12 | describe('Test getChildren()', () => { 13 | it('Test function call', () => expect(knows.getChildren()).toContain(isFriendsWith)); 14 | it('Test function call', () => expect(knows.getChildren().length).toBe(1)); 15 | }); 16 | 17 | describe('Test getDescendants()', () => { 18 | it('Test function call', () => expect(knows.getDescendants()).toContain(isFriendsWith)); 19 | it('Test function call', () => expect(knows.getDescendants()).toContain(isBestFriendsWith)); 20 | it('Test function call', () => expect(knows.getDescendants().length).toBe(2)); 21 | }); 22 | 23 | describe('Test getFilteredDescendants()', () => { 24 | const filter = (descendent: Relation) => descendent === isBestFriendsWith; 25 | 26 | it('Test function call', () => expect(knows.getFilteredDescendants(filter)).toContain(isBestFriendsWith)); 27 | it('Test function call', () => expect(knows.getFilteredDescendants(filter).length).toBe(1)); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml/relation.serialization.test.ts: -------------------------------------------------------------------------------- 1 | import { Project, serializationUtils } from '@libs/ontouml'; 2 | 3 | describe('Test toJSON()', () => { 4 | const model = new Project().createModel(); 5 | const person = model.createClass(); 6 | const knows = model.createMaterialRelation(person, person); 7 | 8 | it('Test serialization', () => expect(() => JSON.stringify(knows)).not.toThrow()); 9 | it('Test serialization validation', () => expect(serializationUtils.validate(knows.project)).toBe(true)); 10 | }); 11 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/general.test.ts: -------------------------------------------------------------------------------- 1 | import { Project } from '@libs/ontouml'; 2 | import { Ontouml2Db, Ontouml2DbOptions } from '@libs/ontouml2db'; 3 | 4 | describe('Tests Ontouml2Db', () => { 5 | describe('Test sample Project transformation', () => { 6 | const project = new Project(); 7 | const model = project.createModel(); 8 | const person = model.createKind('Person'); 9 | 10 | const options = new Ontouml2DbOptions(); 11 | 12 | it('Should not throw exceptions', () => expect(() => new Ontouml2Db(project, options).run()).not.toThrow()); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/generateOntopFiles.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { DbmsSupported } from '@libs/ontouml2db/constants/DbmsSupported'; 7 | import { Ontouml2DbOptions } from '@libs/ontouml2db/Ontouml2DbOptions'; 8 | import { StrategyType } from '@libs/ontouml2db/constants/StrategyType'; 9 | import { baseExample } from './test_resources/baseExample'; 10 | import { Ontouml2Db } from '@libs/ontouml2db'; 11 | 12 | let options: Partial = { 13 | mappingStrategy: StrategyType.ONE_TABLE_PER_KIND, 14 | targetDBMS: DbmsSupported.H2, 15 | isStandardizeNames: true, 16 | hostName: 'localhost/~', 17 | databaseName: 'RunExample', 18 | userConnection: 'sa', 19 | passwordConnection: 'sa' 20 | }; 21 | 22 | test('Run Example', () => { 23 | let ontoUML2DB = new Ontouml2Db(baseExample.project, options); 24 | 25 | let text = ontoUML2DB.getOBDAFile(); 26 | 27 | let files = text.split('|'); 28 | 29 | //console.log(text); 30 | 31 | expect(files.length).toBe(1); 32 | }); 33 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/test_resources/001_simple_flattening.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { GraphChecker } from './graph_tester/GraphChecker'; 7 | import { NodeChecker } from './graph_tester/NodeChecker'; 8 | import { PropertyChecker } from './graph_tester/PropertyChecker'; 9 | import { TrackerChecker } from './graph_tester/TrackerChecker'; 10 | import { TestResource } from './TestResource'; 11 | import { Project } from '@libs/ontouml'; 12 | import { ScriptChecker } from './graph_tester/ScriptChecker'; 13 | import { Ontouml2DbOptions, StrategyType } from '@libs/ontouml2db'; 14 | import { DbmsSupported } from '@libs/ontouml2db/constants/DbmsSupported'; 15 | 16 | // **************************************** 17 | // FOR SCHEMA VALIDATION 18 | // **************************************** 19 | const scriptPerson = 20 | ' CREATE TABLE IF NOT EXISTS person ( ' + 21 | ' person_id INTEGER NOT NULL IDENTITY PRIMARY KEY' + 22 | ', name VARCHAR(20) NOT NULL' + 23 | ', birth_date DATE NOT NULL' + 24 | ');'; 25 | 26 | // **************************************** 27 | // CHECK RESULTING GRAPH 28 | // **************************************** 29 | const gChecker_001_simple_flattening: GraphChecker = new GraphChecker() 30 | .addNode( 31 | new NodeChecker('person') 32 | .addProperty(new PropertyChecker('person_id', false)) 33 | .addProperty(new PropertyChecker('name', false)) 34 | .addProperty(new PropertyChecker('birth_date', false)) 35 | ) 36 | .addTracker(new TrackerChecker('NamedEntity', 'person')) 37 | .addTracker(new TrackerChecker('Person', 'person')) 38 | .setNumberOfTablesToFindInScript(1) 39 | .setNumberOfFkToFindInScript(0) 40 | .addScriptChecker(new ScriptChecker(scriptPerson, 'The PERSON table is different than expected.')); 41 | 42 | // **************************************** 43 | // M O D E L 44 | // **************************************** 45 | const project = new Project(); 46 | const model = project.createModel(); 47 | const namedEntity = model.createCategory('NamedEntity'); 48 | const person = model.createKind('Person'); 49 | const _string = model.createDatatype('string'); 50 | const date = model.createDatatype('Date'); 51 | 52 | model.createGeneralization(namedEntity, person); 53 | const name = namedEntity.createAttribute(_string, 'name'); 54 | const birthDate = person.createAttribute(date, 'birthDate'); 55 | 56 | name.cardinality.setOneToOne(); 57 | birthDate.cardinality.setOneToOne(); 58 | 59 | // **************************************** 60 | // ** O P T I O N S 61 | // **************************************** 62 | const options: Partial = { 63 | mappingStrategy: StrategyType.ONE_TABLE_PER_KIND, 64 | targetDBMS: DbmsSupported.H2, 65 | isStandardizeNames: true, 66 | hostName: 'localhost/~', 67 | databaseName: 'RunExample', 68 | userConnection: 'sa', 69 | passwordConnection: 'sa', 70 | enumFieldToLookupTable: false 71 | }; 72 | 73 | // **************************************** 74 | export const test_001: TestResource = { 75 | title: '001 - Flattening involving only one generalization test', 76 | checker: gChecker_001_simple_flattening, 77 | project, 78 | options 79 | }; 80 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/test_resources/002_flatting_with_duplicate_attributes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { GraphChecker } from './graph_tester/GraphChecker'; 7 | import { NodeChecker } from './graph_tester/NodeChecker'; 8 | import { PropertyChecker } from './graph_tester/PropertyChecker'; 9 | import { TrackerChecker } from './graph_tester/TrackerChecker'; 10 | import { TestResource } from './TestResource'; 11 | import { Project } from '@libs/ontouml'; 12 | import { ScriptChecker } from './graph_tester/ScriptChecker'; 13 | import { Ontouml2DbOptions, StrategyType } from '@libs/ontouml2db'; 14 | import { DbmsSupported } from '@libs/ontouml2db/constants/DbmsSupported'; 15 | 16 | // **************************************** 17 | // FOR SCHEMA VALIDATION 18 | // **************************************** 19 | const scriptPerson = 20 | ' CREATE TABLE IF NOT EXISTS person ( ' + 21 | ' person_id INTEGER NOT NULL IDENTITY PRIMARY KEY' + 22 | ', x2 VARCHAR(20) NULL' + 23 | ', x1 INTEGER NULL' + 24 | ', x3 VARCHAR(20) NULL' + 25 | ');'; 26 | 27 | // **************************************** 28 | // CHECK RESULTING GRAPH 29 | // **************************************** 30 | 31 | const gChecker_002_flatting_with_duplicate_attributes = new GraphChecker() 32 | .addNode( 33 | new NodeChecker('person') 34 | .addProperty(new PropertyChecker('person_id', false)) 35 | .addProperty(new PropertyChecker('x1', true)) 36 | .addProperty(new PropertyChecker('x2', true)) 37 | .addProperty(new PropertyChecker('x3', true)) 38 | ) 39 | .addTracker(new TrackerChecker('NamedEntity', 'person')) 40 | .addTracker(new TrackerChecker('Person', 'person')) 41 | .setNumberOfTablesToFindInScript(1) 42 | .setNumberOfFkToFindInScript(0) 43 | .addScriptChecker(new ScriptChecker(scriptPerson, 'The PERSON table is different than expected.')); 44 | 45 | // **************************************** 46 | // M O D E L 47 | // **************************************** 48 | const project = new Project(); 49 | const model = project.createModel(); 50 | 51 | // CREATE TYPES 52 | const _int = model.createDatatype('int'); 53 | const _string = model.createDatatype('string'); 54 | 55 | // CREATE CLASSES 56 | const namedEntity = model.createCategory('NamedEntity'); 57 | const person = model.createKind('Person'); 58 | // CREATE PROPERTIES 59 | namedEntity.createAttribute(_int, 'x1'); 60 | namedEntity.createAttribute(_string, 'x2'); 61 | person.createAttribute(_int, 'x1'); 62 | person.createAttribute(_string, 'x3'); 63 | // CREATE GENERALIZATIONS 64 | model.createGeneralization(namedEntity, person); 65 | 66 | // **************************************** 67 | // ** O P T I O N S 68 | // **************************************** 69 | const options: Partial = { 70 | mappingStrategy: StrategyType.ONE_TABLE_PER_KIND, 71 | targetDBMS: DbmsSupported.H2, 72 | isStandardizeNames: true, 73 | hostName: 'localhost/~', 74 | databaseName: 'RunExample', 75 | userConnection: 'sa', 76 | passwordConnection: 'sa', 77 | enumFieldToLookupTable: false 78 | }; 79 | 80 | // **************************************** 81 | export const test_002: TestResource = { 82 | title: '002 - Flattening where there are attributes with the same name in the superclass and subclass', 83 | checker: gChecker_002_flatting_with_duplicate_attributes, 84 | project, 85 | options 86 | }; 87 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/test_resources/012_simple_lifting.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { Project } from '@libs/ontouml'; 7 | import { GraphChecker } from './graph_tester/GraphChecker'; 8 | import { NodeChecker } from './graph_tester/NodeChecker'; 9 | import { PropertyChecker } from './graph_tester/PropertyChecker'; 10 | import { ScriptChecker } from './graph_tester/ScriptChecker'; 11 | import { TrackerChecker } from './graph_tester/TrackerChecker'; 12 | import { TestResource } from './TestResource'; 13 | import { Ontouml2DbOptions, StrategyType } from '@libs/ontouml2db'; 14 | import { DbmsSupported } from '@libs/ontouml2db/constants/DbmsSupported'; 15 | 16 | // **************************************** 17 | // FOR SCHEMA VALIDATION 18 | // **************************************** 19 | const scriptPerson = 20 | 'CREATE TABLE IF NOT EXISTS person ( ' + 21 | ' person_id INTEGER NOT NULL IDENTITY PRIMARY KEY' + 22 | ', birth_date DATE NOT NULL' + 23 | ', test VARCHAR(20) NULL' + 24 | ', is_employee BOOLEAN NOT NULL DEFAULT FALSE' + 25 | '); '; 26 | 27 | // **************************************** 28 | // CHECK RESULTING GRAPH 29 | // **************************************** 30 | const gChecker_012_simple_lifting = new GraphChecker() 31 | .addNode( 32 | new NodeChecker('person') 33 | .addProperty(new PropertyChecker('person_id', false)) 34 | .addProperty(new PropertyChecker('birth_date', false)) 35 | .addProperty(new PropertyChecker('test', true)) 36 | .addProperty(new PropertyChecker('is_employee', false)) 37 | ) 38 | .addTracker(new TrackerChecker('Person', 'person')) 39 | .addTracker(new TrackerChecker('Employee', 'person')) 40 | .setNumberOfTablesToFindInScript(1) 41 | .setNumberOfFkToFindInScript(0) 42 | .addScriptChecker(new ScriptChecker(scriptPerson, 'The PERSON table is different than expected.')); 43 | 44 | // **************************************** 45 | // M O D E L 46 | // **************************************** 47 | const project = new Project(); 48 | const model = project.createModel(); 49 | // CREATE TYPES 50 | const _string = model.createDatatype('string'); 51 | const _date = model.createDatatype('Date'); 52 | // CREATE CLASSES 53 | const person = model.createKind('Person'); 54 | const employee = model.createRole('Employee'); 55 | // CREATE PROPERTIES 56 | person.createAttribute(_date, 'birthDate').cardinality.setOneToOne(); 57 | employee.createAttribute(_string, 'test').cardinality.setOneToOne(); 58 | // CREATE GENERALIZATIONS 59 | model.createGeneralization(person, employee); 60 | 61 | // **************************************** 62 | // ** O P T I O N S 63 | // **************************************** 64 | const options: Partial = { 65 | mappingStrategy: StrategyType.ONE_TABLE_PER_KIND, 66 | targetDBMS: DbmsSupported.H2, 67 | isStandardizeNames: true, 68 | hostName: 'localhost/~', 69 | databaseName: 'RunExample', 70 | userConnection: 'sa', 71 | passwordConnection: 'sa', 72 | enumFieldToLookupTable: false 73 | }; 74 | 75 | // **************************************** 76 | export const test_012: TestResource = { 77 | title: '012 - Lifting with a simple generalization', 78 | checker: gChecker_012_simple_lifting, 79 | project, 80 | options 81 | }; 82 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/test_resources/037_test_generic_db_without_lookup_tabele_for_enums.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { GraphChecker } from './graph_tester/GraphChecker'; 7 | import { TestResource } from './TestResource'; 8 | import { Project } from '@libs/ontouml'; 9 | import { Ontouml2DbOptions, StrategyType } from '@libs/ontouml2db'; 10 | import { DbmsSupported } from '@libs/ontouml2db/constants/DbmsSupported'; 11 | 12 | // **************************************** 13 | // FOR SCHEMA VALIDATION 14 | // **************************************** 15 | 16 | // **************************************** 17 | // CHECK RESULTING GRAPH 18 | // **************************************** 19 | const gChecker_037: GraphChecker = new GraphChecker(); 20 | 21 | // **************************************** 22 | // M O D E L 23 | // **************************************** 24 | const project = new Project(); 25 | 26 | // **************************************** 27 | // ** O P T I O N S 28 | // **************************************** 29 | const options: Partial = { 30 | mappingStrategy: StrategyType.ONE_TABLE_PER_KIND, 31 | targetDBMS: DbmsSupported.GENERIC_SCHEMA, 32 | isStandardizeNames: true, 33 | hostName: 'localhost/~', 34 | databaseName: 'RunExample', 35 | userConnection: 'sa', 36 | passwordConnection: 'sa', 37 | enumFieldToLookupTable: false 38 | }; 39 | 40 | // **************************************** 41 | export const test_037: TestResource = { 42 | title: '037 - Evaluate the transformatino for GENERIC dbms without lookup table for enumerations.', 43 | checker: gChecker_037, 44 | project, 45 | options 46 | }; 47 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/test_resources/TestResource.ts: -------------------------------------------------------------------------------- 1 | // import { ModelManager } from 'src'; 2 | import { GraphChecker } from './graph_tester/GraphChecker'; 3 | import { Project } from '@libs/ontouml'; 4 | import { OntoUML2DBOptions } from '@libs/ontouml2db'; 5 | 6 | export interface TestResource { 7 | title: string; 8 | checker: GraphChecker; 9 | project: Project; 10 | options: Partial; 11 | } 12 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/test_resources/graph_tester/NodeChecker.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { PropertyChecker } from './PropertyChecker'; 7 | import { Node } from '@libs/ontouml2db/graph/Node'; 8 | import { Graph } from '@libs/ontouml2db/graph/Graph'; 9 | 10 | export class NodeChecker { 11 | private name: string; 12 | private properties: PropertyChecker[]; 13 | 14 | constructor(name: string) { 15 | this.name = name; 16 | this.properties = []; 17 | } 18 | 19 | addProperty(property: PropertyChecker): NodeChecker { 20 | this.properties.push(property); 21 | return this; 22 | } 23 | 24 | check(graph: Graph): string { 25 | let result = ''; 26 | let node: Node; 27 | 28 | node = graph.getNodeByName(this.name); 29 | 30 | if (node === null) { 31 | return "The node '" + this.name + "' was not found."; 32 | } 33 | 34 | for (let val of this.properties) { 35 | result = val.check(node); 36 | if (result != '') return result; 37 | } 38 | 39 | if (this.properties.length != node.getProperties().length) { 40 | return "The amount of properties does not match for the node '" + this.name + "'."; 41 | } 42 | 43 | return result; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/test_resources/graph_tester/OntoUML2DBOptions_TO_BE_DELETED.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | /* 6 | import { OntoUML2DBOptions } from '@libs/ontouml2db/OntoUML2DBOptions'; 7 | import { StrategyType } from '@libs/ontouml2db/constants/StrategyType'; 8 | import { DBMSSupported } from '@libs/ontouml2db/constants/DBMSSupported'; 9 | 10 | 11 | 12 | export class OntoUML2DBOptions implements OntoUML2DBOptions { 13 | hostName: string; 14 | databaseName: string; 15 | userConnection: string; 16 | passwordConnection: string; 17 | strategyType: StrategyType; 18 | dbms: DBMSSupported; 19 | standardizeNames?: boolean; 20 | } 21 | */ 22 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/test_resources/graph_tester/PropertyChecker.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { NodeProperty } from '@libs/ontouml2db/graph/NodeProperty'; 7 | import { Node } from '@libs/ontouml2db/graph/Node'; 8 | import { NodePropertyEnumeration } from '@libs/ontouml2db/graph/NodePropertyEnumeration'; 9 | 10 | export class PropertyChecker { 11 | private name: string; 12 | private nullable: boolean; 13 | private enumValues: string[]; 14 | 15 | constructor(name: string, nullable: boolean, enumValues?: string[]) { 16 | this.name = name; 17 | this.nullable = nullable; 18 | this.enumValues = enumValues; 19 | } 20 | 21 | check(node: Node): string { 22 | let property: NodeProperty; 23 | 24 | property = node.getPropertyByName(this.name); 25 | 26 | if (property === null) return "The '" + this.name + "' property was not found in '" + node.getName() + "' node."; 27 | 28 | if (this.nullable != property.isNullable()) { 29 | return "The annulability of '" + this.name + "' in '" + node.getName() + "' table is different form the graph."; 30 | } 31 | 32 | if (this.enumValues != null) { 33 | let enumProperty = property as NodePropertyEnumeration; 34 | 35 | for (let val of this.enumValues) { 36 | if (!enumProperty.getValues().includes(val)) { 37 | return "The enumeration '" + this.name + "' does not include the value + '" + val + "'."; 38 | } 39 | } 40 | if (this.enumValues.length != enumProperty.getValues().length) 41 | return "The number of values in the '" + this.name + "' enumeration does not match."; 42 | } 43 | 44 | return ''; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/test_resources/graph_tester/RelationshipChecker.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: Gustavo Ludovico Guidoni 3 | */ 4 | 5 | import { Cardinality } from '@libs/ontouml2db/constants/enumerations'; 6 | import { Graph } from '@libs/ontouml2db/graph/Graph'; 7 | import { GraphAssociation } from '@libs/ontouml2db/graph/GraphAssociation'; 8 | import { GraphRelation } from '@libs/ontouml2db/graph/GraphRelation'; 9 | 10 | export class RelationshipChecker { 11 | private sourceNodeName: string; 12 | private sourceCardinality: Cardinality; 13 | private targetNodeName: string; 14 | private targetCardinality: Cardinality; 15 | 16 | constructor(sourceNode: string, sourceCardinality: Cardinality, targetNode: string, targetCardinality: Cardinality) { 17 | this.sourceNodeName = sourceNode; 18 | this.sourceCardinality = sourceCardinality; 19 | this.targetNodeName = targetNode; 20 | this.targetCardinality = targetCardinality; 21 | } 22 | 23 | check(graph: Graph): string { 24 | //Checks whether the associations are the same. 25 | if (!this.existsAssociation(graph.getAssociations())) { 26 | return ( 27 | "The relationship '" + 28 | this.sourceNodeName + 29 | ' - ' + 30 | this.targetNodeName + 31 | "' not exists or the cardinalities are not the same." 32 | ); 33 | } 34 | return ''; 35 | } 36 | 37 | existsAssociation(associations: GraphAssociation[]): boolean { 38 | for (let relation of associations as GraphRelation[]) { 39 | if ( 40 | (relation.getSourceNode().getName() === this.sourceNodeName && 41 | relation.getSourceCardinality() === this.sourceCardinality && 42 | relation.getTargetNode().getName() === this.targetNodeName && 43 | relation.getTargetCardinality() === this.targetCardinality) || 44 | (relation.getSourceNode().getName() === this.targetNodeName && 45 | relation.getSourceCardinality() === this.targetCardinality && 46 | relation.getTargetNode().getName() === this.sourceNodeName && 47 | relation.getTargetCardinality() === this.sourceCardinality) 48 | ) { 49 | return true; 50 | } 51 | } 52 | return false; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/test_resources/graph_tester/ScriptChecker.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { countPattern, removeBlankSpaces } from './functions'; 7 | 8 | export class ScriptChecker { 9 | private script: string; 10 | private msg: string; 11 | 12 | constructor(script: string, msg: string) { 13 | this.script = removeBlankSpaces(script); 14 | this.msg = msg; 15 | } 16 | 17 | check(schema: string): string { 18 | if (countPattern(schema, this.script) != 1) { 19 | return this.msg; 20 | } else { 21 | return ''; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/test_resources/graph_tester/TrackerChecker.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { Tracker } from '@libs/ontouml2db/tracker/Tracker'; 7 | 8 | export class TrackerChecker { 9 | private sourceNodeName: string; 10 | private targetNodeName: string; 11 | 12 | constructor(sourceNode: string, targetNode: string) { 13 | this.sourceNodeName = sourceNode; 14 | this.targetNodeName = targetNode; 15 | } 16 | 17 | getSourceNodeName(): string { 18 | return this.sourceNodeName; 19 | } 20 | 21 | getTargetNodeName(): string { 22 | return this.targetNodeName; 23 | } 24 | 25 | check(tracker: Tracker): string { 26 | if (!tracker.existsTracerByName(this.sourceNodeName, this.targetNodeName)) { 27 | return 'Not find the tracer: ' + this.sourceNodeName + ' - ' + this.targetNodeName; 28 | } 29 | 30 | return ''; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2db/test_resources/graph_tester/functions.ts: -------------------------------------------------------------------------------- 1 | export function countPattern(schema: string, pattern: string): number { 2 | return (schema.match(new RegExp(pattern, 'g')) || []).length; 3 | } 4 | 5 | export function removeBlankSpaces(text: string): string { 6 | return text 7 | .replace(/\s/g, '') 8 | .replace(/\(/g, '') 9 | .replace(/\)/g, ''); 10 | } 11 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2gufo/description.test.ts: -------------------------------------------------------------------------------- 1 | import { generateGufo } from './helpers'; 2 | import { Package } from '@libs/ontouml'; 3 | 4 | describe('Descriptions to rdfs:comments', () => { 5 | it('should generate class "description" as a rdfs:comment', () => { 6 | const model = new Package(); 7 | const _class = model.createKind('Person'); 8 | const description = 'This is a description of the person class.'; 9 | _class.addDescription(description); 10 | 11 | const result = generateGufo(model); 12 | 13 | expect(result).toContain('<:Person> "' + description + '"'); 14 | }); 15 | 16 | it('should generate attribute "description" as a rdfs:comment', () => { 17 | const model = new Package(); 18 | const _class = model.createKind('Person'); 19 | const datatype = model.createDatatype('string'); 20 | const attr = _class.createAttribute(datatype, 'name'); 21 | const description = 'This is the description of the attribute name in of the person class.'; 22 | 23 | attr.addDescription(description); 24 | 25 | const result = generateGufo(model); 26 | 27 | expect(result).toContain('<:name> "' + description + '"'); 28 | }); 29 | 30 | it('should generate association "description" as a rdfs:comment', () => { 31 | const model = new Package(); 32 | const _class = model.createKind('Person'); 33 | const relation = model.createMaterialRelation(_class, _class, 'knows'); 34 | const description = 'This is the description of the relation knows.'; 35 | 36 | relation.addDescription(description); 37 | 38 | const result = generateGufo(model); 39 | 40 | expect(result).toContain('<:knows> "' + description + '"'); 41 | 42 | const regex = new RegExp(description, 'g'); 43 | var matches = (result.match(regex) || []).length; 44 | expect(matches).toEqual(1); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2gufo/enumeration.test.ts: -------------------------------------------------------------------------------- 1 | import { generateGufo } from './helpers'; 2 | import { Package } from '@libs/ontouml'; 3 | 4 | describe('Enumeration', () => { 5 | let result; 6 | 7 | beforeAll(async () => { 8 | const model = new Package(); 9 | const _class = model.createEnumeration('Color'); 10 | 11 | _class.createLiteral('blue'); 12 | _class.createLiteral('red'); 13 | _class.createLiteral('green'); 14 | 15 | result = generateGufo(model); 16 | }); 17 | 18 | it('should transform «enumeration» class', async () => { 19 | expect(result).toContain('<:Color> '); 20 | expect(result).toContain('<:Color> '); 21 | }); 22 | 23 | it('should create equivalentClass with literals', async () => { 24 | expect(result).toContain('<:Color> '); 25 | expect(result).toContain(' (<:blue> <:red> <:green>)'); 26 | }); 27 | 28 | it('should transform literals', async () => { 29 | expect(result).toContain('<:blue> <:Color> .'); 30 | expect(result).toContain('<:red> <:Color> .'); 31 | expect(result).toContain('<:green> <:Color> .'); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2gufo/generalizations.test.ts: -------------------------------------------------------------------------------- 1 | import { generateGufo } from './helpers'; 2 | import { Package } from '@libs/ontouml'; 3 | 4 | describe('Generalizations', () => { 5 | it('Between classes', () => { 6 | const model = new Package(); 7 | const parent = model.createKind('Person'); 8 | const child = model.createSubkind('Man'); 9 | model.createGeneralization(parent, child); 10 | 11 | const owl = generateGufo(model); 12 | expect(owl).toContain('<:Man> <:Person>'); 13 | }); 14 | 15 | it('Between classes without stereotypes', () => { 16 | const model = new Package(); 17 | const parent = model.createClass('Person'); 18 | const child = model.createClass('Man'); 19 | model.createGeneralization(parent, child); 20 | 21 | const owl = generateGufo(model); 22 | expect(owl).toContain('<:Man> <:Person>'); 23 | }); 24 | 25 | it('Between relations', () => { 26 | const model = new Package(); 27 | const _class = model.createKind('Person'); 28 | const parent = model.createMaterialRelation(_class, _class, 'likes'); 29 | const child = model.createMaterialRelation(_class, _class, 'loves'); 30 | model.createGeneralization(parent, child); 31 | 32 | const owl = generateGufo(model); 33 | expect(owl).toContain('<:loves> <:likes>'); 34 | }); 35 | 36 | it('Between relations without stereotypes', () => { 37 | const model = new Package(); 38 | const _class = model.createKind('Person'); 39 | const parent = model.createBinaryRelation(_class, _class, 'likes'); 40 | const child = model.createBinaryRelation(_class, _class, 'loves'); 41 | model.createGeneralization(parent, child); 42 | 43 | const owl = generateGufo(model); 44 | expect(owl).toContain('<:loves> <:likes>'); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2gufo/helpers.ts: -------------------------------------------------------------------------------- 1 | import { Package, Project } from '@libs/ontouml'; 2 | import { Ontouml2Gufo, Ontouml2GufoOptions, Issue, UriManager } from '@libs/ontouml2gufo'; 3 | 4 | export function generateGufo(modelOrProject: Package | Project, options?: Partial): string { 5 | const optionsWithDefaults = { 6 | baseIri: 'https://example.com', 7 | format: 'N-Triple', 8 | ...options 9 | }; 10 | const ontouml2gufo = new Ontouml2Gufo(modelOrProject, optionsWithDefaults); 11 | 12 | ontouml2gufo.transform(); 13 | 14 | return ontouml2gufo.getOwlCode(); 15 | // TODO: replace with static method 16 | } 17 | 18 | export function getIssues(modelOrProject: Package | Project, options?: Partial): Issue[] { 19 | const optionsWithDefaults = { 20 | baseIri: 'https://example.com', 21 | format: 'Turtle', 22 | ...options 23 | }; 24 | const ontouml2gufo = new Ontouml2Gufo(modelOrProject, optionsWithDefaults); 25 | 26 | ontouml2gufo.transform(); 27 | 28 | return ontouml2gufo.getIssues(); 29 | } 30 | 31 | export function getUriManager(modelOrProject: Package | Project, options?: Partial): UriManager { 32 | const optionsWithDefaults = { 33 | baseIri: 'https://example.com', 34 | format: 'Turtle', 35 | ...options 36 | }; 37 | const ontouml2gufo = new Ontouml2Gufo(modelOrProject, optionsWithDefaults); 38 | 39 | return ontouml2gufo.uriManager; 40 | } 41 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2gufo/names.test.ts: -------------------------------------------------------------------------------- 1 | import { generateGufo } from './helpers'; 2 | import { Package } from '@libs/ontouml'; 3 | 4 | describe('Names to labels', () => { 5 | it('should generate labels without language tags when names are simple strings', () => { 6 | const model = new Package(); 7 | model.addName('My Model'); 8 | 9 | model.createKind('Person'); 10 | const result = generateGufo(model); 11 | 12 | expect(result).toContain('<:Person> "Person"'); 13 | }); 14 | 15 | it('should generate language labels on classess using 2-letter IANA language tags (e.g. en, it)', () => { 16 | const model = new Package(); 17 | const clazz = model.createKind(); 18 | clazz.name.addAll({ 19 | en: 'Person', 20 | it: 'Persona' 21 | }); 22 | 23 | const result = generateGufo(model); 24 | 25 | expect(result).toContain('<:Person> "Person"@en'); 26 | expect(result).toContain('<:Person> "Persona"@it'); 27 | }); 28 | 29 | it('should generate language labels on classess using composed IANA language tags (e.g. en-us, pt-br)', () => { 30 | const model = new Package(); 31 | model.addName('My Model'); 32 | 33 | const clazz = model.createKind(); 34 | clazz.name.addAll({ 35 | 'en-us': 'Person', 36 | 'pt-br': 'Pessoa' 37 | }); 38 | 39 | const result = generateGufo(model); 40 | 41 | expect(result).toContain('<:Person> "Person"@en-us'); 42 | expect(result).toContain('<:Person> "Pessoa"@pt-br'); 43 | }); 44 | 45 | it('should NOT generate language labels for invalid IANA language tags (e.g. ens, it-trento, xyz)', () => { 46 | const model = new Package(); 47 | const clazz = model.createKind(null, { id: '123' }); 48 | clazz.name.addAll({ 49 | ens: 'Person', 50 | 'it-trento': 'Persona', 51 | xyz: 'Persoon' 52 | }); 53 | 54 | const result = generateGufo(model); 55 | 56 | expect(result).not.toContain('<:123> "Persona"@it-trento'); 57 | expect(result).not.toContain('<:123> "Person"@ens'); 58 | expect(result).not.toContain('<:123> "Persoon"@xyz'); 59 | }); 60 | 61 | it('should generate language labels on attributes (e.g. nl, pt)', () => { 62 | const model = new Package(); 63 | const person = model.createKind('Person'); 64 | const datatype = model.createKind('string'); 65 | 66 | const attr = person.createAttribute(datatype); 67 | attr.name.addAll({ nl: 'naam', pt: 'nome' }); 68 | 69 | const result = generateGufo(model); 70 | 71 | expect(result).toContain('<:naam> "naam"@nl'); 72 | expect(result).toContain('<:naam> "nome"@pt'); 73 | }); 74 | 75 | it('should generate language labels on relations (e.g. de, sv)', () => { 76 | const model = new Package(); 77 | const person = model.createKind('Person'); 78 | 79 | const rel = model.createMaterialRelation(person, person); 80 | rel.name.addAll({ de: 'kennt', sv: 'känner' }); 81 | 82 | const result = generateGufo(model); 83 | 84 | expect(result).toContain('<:kennt> "kennt"@de'); 85 | expect(result).toContain('<:kennt> "känner"@sv'); 86 | }); 87 | }); 88 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2gufo/subpackages.test.ts: -------------------------------------------------------------------------------- 1 | import { generateGufo } from './helpers'; 2 | import { Package } from '@libs/ontouml'; 3 | 4 | describe('Subpackages', () => { 5 | let model: Package; 6 | 7 | beforeEach(() => { 8 | model = new Package(); 9 | const universityPkg = model.createPackage('University'); 10 | universityPkg.createKind('Person'); 11 | }); 12 | 13 | describe('When { prefixPackages = true }', () => { 14 | it("should generate subpackage prefix based on the package's name", () => { 15 | const owlCode = generateGufo(model, { format: 'Turtle', prefixPackages: true }); 16 | expect(owlCode).toContain('@prefix university:'); 17 | }); 18 | 19 | it("should generate subpackage URI based on the package's name and the supplied baseIri", () => { 20 | const owlCode = generateGufo(model, { format: 'Turtle', prefixPackages: true, baseIri: 'http://ontouml.org' }); 21 | expect(owlCode).toContain('@prefix university: '); 22 | }); 23 | 24 | it('should use the generated subpackage prefix for the elements the subpackage contains', () => { 25 | const owlCode = generateGufo(model, { format: 'Turtle', prefixPackages: true }); 26 | expect(owlCode).toContain('university:Person'); 27 | }); 28 | }); 29 | 30 | describe('When { prefixPackages = false }', () => { 31 | it("should NOT generate subpackage prefix based on the package's name", () => { 32 | const owlCode = generateGufo(model, { format: 'Turtle', prefixPackages: false }); 33 | expect(owlCode).not.toContain('@prefix university:'); 34 | }); 35 | 36 | it('should use the default prefix for the elements the subpackage contains', () => { 37 | const owlCode = generateGufo(model, { format: 'Turtle', prefixPackages: false }); 38 | expect(owlCode).toContain(':Person'); 39 | expect(owlCode).not.toContain('university:Person'); 40 | }); 41 | }); 42 | 43 | describe('When { prefixPackages = true } and there are custom mappings for packages', () => { 44 | it('should generate subpackage prefix equal to the provided value', () => { 45 | const owlCode = generateGufo(model, { 46 | format: 'Turtle', 47 | prefixPackages: true, 48 | customPackageMapping: { 49 | University: { 50 | prefix: 'uni' 51 | } 52 | } 53 | }); 54 | expect(owlCode).toContain('@prefix uni:'); 55 | }); 56 | 57 | it('should generate subpackage URI equal to the provided value', () => { 58 | const owlCode = generateGufo(model, { 59 | format: 'Turtle', 60 | prefixPackages: true, 61 | customPackageMapping: { 62 | University: { 63 | uri: 'http://university.org/' 64 | } 65 | } 66 | }); 67 | expect(owlCode).toContain('@prefix university: { 71 | const owlCode = generateGufo(model, { 72 | format: 'Turtle', 73 | prefixPackages: true, 74 | customPackageMapping: { 75 | University: { 76 | prefix: 'uni' 77 | } 78 | } 79 | }); 80 | expect(owlCode).toContain('uni:Person'); 81 | }); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2gufo/uri_name_normalization.test.ts: -------------------------------------------------------------------------------- 1 | import { normalizeName } from '@libs/ontouml2gufo/uri_manager'; 2 | 3 | describe('Original case is kept when there are no spaces', () => { 4 | it('Person -> Person', () => { 5 | const normalized = normalizeName('Person'); 6 | expect(normalized).toBe('Person'); 7 | }); 8 | 9 | it('PERSON -> PERSON', () => { 10 | const normalized = normalizeName('PERSON'); 11 | expect(normalized).toBe('PERSON'); 12 | }); 13 | 14 | it('person -> person', () => { 15 | const normalized = normalizeName('person'); 16 | expect(normalized).toBe('person'); 17 | }); 18 | 19 | it('PeRsoN -> PeRsoN', () => { 20 | const normalized = normalizeName('PeRsoN'); 21 | expect(normalized).toBe('PeRsoN'); 22 | }); 23 | }); 24 | 25 | describe('Normalized names only have letters, digits, and underscore', () => { 26 | it('Adult_Person -> Adult_Person', () => { 27 | const normalized = normalizeName('Adult_Person'); 28 | expect(normalized).toBe('Adult_Person'); 29 | }); 30 | 31 | it('Person2 -> Person2', () => { 32 | const normalized = normalizeName('Person2'); 33 | expect(normalized).toBe('Person2'); 34 | }); 35 | 36 | it('1Person -> 1Person', () => { 37 | const normalized = normalizeName('Person@'); 38 | expect(normalized).toBe('Person'); 39 | }); 40 | 41 | it('Person@ -> Person', () => { 42 | const normalized = normalizeName('Person@'); 43 | expect(normalized).toBe('Person'); 44 | }); 45 | 46 | it('Per:son -> Person', () => { 47 | const normalized = normalizeName('Per:son'); 48 | expect(normalized).toBe('Person'); 49 | }); 50 | 51 | it('!Person -> Person', () => { 52 | const normalized = normalizeName('!Person'); 53 | expect(normalized).toBe('Person'); 54 | }); 55 | 56 | it('Per-son -> Person', () => { 57 | const normalized = normalizeName('Per-son'); 58 | expect(normalized).toBe('PerSon'); 59 | }); 60 | 61 | it('" Person" -> Person', () => { 62 | const normalized = normalizeName(' Person'); 63 | expect(normalized).toBe('Person'); 64 | }); 65 | 66 | it('"Person " -> Person', () => { 67 | const normalized = normalizeName('Person '); 68 | expect(normalized).toBe('Person'); 69 | }); 70 | }); 71 | 72 | describe('Spaces followed by a letter are capitalized', () => { 73 | it('"Adult person" -> AdultPerson', () => { 74 | const normalized = normalizeName('Adult person'); 75 | expect(normalized).toBe('AdultPerson'); 76 | }); 77 | 78 | it('Adult person -> AdultPerson', () => { 79 | const normalized = normalizeName('Adult person'); 80 | expect(normalized).toBe('AdultPerson'); 81 | }); 82 | 83 | it('married with -> marriedWith', () => { 84 | const normalized = normalizeName('married with'); 85 | expect(normalized).toBe('marriedWith'); 86 | }); 87 | 88 | it('Married With -> MarriedWith', () => { 89 | const normalized = normalizeName('Married With'); 90 | expect(normalized).toBe('MarriedWith'); 91 | }); 92 | 93 | it('MARRIED WITH -> MARRIEDWITH', () => { 94 | const normalized = normalizeName('MARRIED WITH'); 95 | expect(normalized).toBe('MARRIEDWITH'); 96 | }); 97 | }); 98 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/class_views.test.ts: -------------------------------------------------------------------------------- 1 | import { Project } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe('Class views', () => { 8 | let result: string; 9 | 10 | beforeAll(() => { 11 | const project = new Project(); 12 | 13 | const model = project.createModel({ id: 'pk1' }); 14 | const class1 = model.createKind(null, { id: 'c1' }); 15 | 16 | const diagram = project.createDiagram({ id: 'd1' }); 17 | const classView1 = diagram.addClass(class1); 18 | classView1.id = 'cv1'; 19 | classView1.shape.id = 'sh1'; 20 | 21 | result = generateOwl(project, baseUri, prefix); 22 | }); 23 | 24 | it('should generate rdf:type triple', () => { 25 | expect(result).toContain(' '); 26 | }); 27 | 28 | it('should generate is view of triple', () => { 29 | expect(result).toContain(' '); 30 | }); 31 | 32 | it('should generate relation view content triple', () => { 33 | expect(result).toContain(' '); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/classes.test.ts: -------------------------------------------------------------------------------- 1 | import { OntologicalNature, Package, Project, Class } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe('Classes', () => { 8 | let result: string; 9 | 10 | beforeEach(() => { 11 | const project = new Project(); 12 | const model = project.createModel(); 13 | const clazz = model.createKind(null, { id: 'c1' }); 14 | clazz.setName('Happy Person', 'en'); 15 | clazz.setDescription('A person who is happy', 'en'); 16 | clazz.isAbstract = true; 17 | clazz.isDerived = true; 18 | clazz.isPowertype = true; 19 | clazz.isExtensional = true; 20 | clazz.order = 2; 21 | clazz.createAttribute(clazz, null, { id: 'a1' }); 22 | model.createKind(null, { id: '.c2.' }); 23 | 24 | result = generateOwl(project, baseUri, prefix); 25 | }); 26 | 27 | it('should generate rdf:type triple', () => { 28 | expect(result).toContain(' '); 29 | }); 30 | 31 | it('should handle special characters on class id', () => { 32 | expect(result).toContain(' '); 33 | }); 34 | 35 | it('should generate stereotype triple', () => { 36 | expect(result).toContain( 37 | ' ' 38 | ); 39 | }); 40 | 41 | it('should generate restrictedTo triple (functionalComplex)', () => { 42 | expect(result).toContain( 43 | ' ' 44 | ); 45 | }); 46 | 47 | it('should generate name triple', () => { 48 | expect(result).toContain(' "Happy Person"@en'); 49 | }); 50 | 51 | it('should generate description triple', () => { 52 | expect(result).toContain(' "A person who is happy"@en'); 53 | }); 54 | 55 | it('should generate isAbstract triple', () => { 56 | expect(result).toContain(' "true"^^'); 57 | }); 58 | 59 | it('should generate isDerived triple', () => { 60 | expect(result).toContain(' "true"^^'); 61 | }); 62 | 63 | it('should generate isPowertype triple', () => { 64 | expect(result).toContain(' "true"^^'); 65 | }); 66 | 67 | it('should generate isExtensional triple', () => { 68 | expect(result).toContain(' "true"^^'); 69 | }); 70 | 71 | it('should generate higher order triple', () => { 72 | expect(result).toContain(' "2"^^'); 73 | }); 74 | 75 | it('should generate attribute triple', () => { 76 | expect(result).toContain(' '); 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/generalization_sets.test.ts: -------------------------------------------------------------------------------- 1 | import { Package, Project, Class, Generalization, GeneralizationSet } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe('Generalization sets', () => { 8 | let project: Project; 9 | let model: Package; 10 | let parent, child1, child2, categorizer: Class; 11 | let gen1, gen2: Generalization; 12 | let gs: GeneralizationSet; 13 | let result: String; 14 | 15 | beforeAll(() => { 16 | project = new Project(); 17 | model = project.createModel(); 18 | parent = model.createKind(null, { id: 'c1' }); 19 | child1 = model.createSubkind(null, null, { id: 'c2' }); 20 | child2 = model.createSubkind(null, null, { id: 'c3' }); 21 | categorizer = model.createType(null, { id: 'c4' }); 22 | gen1 = model.createGeneralization(parent, child1, null, { id: 'g1' }); 23 | gen2 = model.createGeneralization(parent, child2, null, { id: 'g2' }); 24 | gs = model.createGeneralizationSet([gen1, gen2], true, true, categorizer, null, { id: 'gs1' }); 25 | gs.setName('status', 'en'); 26 | gs.setDescription('gs 1 description', 'en'); 27 | 28 | result = generateOwl(project, baseUri, prefix); 29 | }); 30 | 31 | it('should generate rdf:type triple', () => { 32 | expect(result).toContain(' '); 33 | }); 34 | 35 | it('should generate generalization triples', () => { 36 | expect(result).toContain(' '); 37 | expect(result).toContain(' '); 38 | }); 39 | 40 | it('should generate categorizer triple', () => { 41 | expect(result).toContain(' '); 42 | }); 43 | 44 | it('should generate isDisjoint triple', () => { 45 | expect(result).toContain(' "true"^^'); 46 | }); 47 | 48 | it('should generate isComplete triple', () => { 49 | expect(result).toContain(' "true"^^'); 50 | }); 51 | 52 | it('should generate name triple', () => { 53 | expect(result).toContain(' "status"@en'); 54 | }); 55 | 56 | it('should generate description triple', () => { 57 | expect(result).toContain(' "gs 1 description"@en'); 58 | }); 59 | }); 60 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/generalizations.test.ts: -------------------------------------------------------------------------------- 1 | import { Package, Project, Class, Generalization } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe('Generalizations', () => { 8 | let project: Project; 9 | let model: Package; 10 | let parent, child: Class; 11 | let generalization: Generalization; 12 | 13 | beforeEach(() => { 14 | project = new Project(); 15 | model = project.createModel(); 16 | parent = model.createKind(null, { id: 'c1' }); 17 | child = model.createSubkind(null, null, { id: 'c2' }); 18 | generalization = model.createGeneralization(parent, child, null, { id: 'g1' }); 19 | }); 20 | 21 | it('should generate rdf:type triple', () => { 22 | const result = generateOwl(project, baseUri, prefix); 23 | expect(result).toContain(' '); 24 | }); 25 | 26 | it('should generate name triple', () => { 27 | generalization.setName('gen 1', 'en'); 28 | 29 | const result = generateOwl(project, baseUri, prefix); 30 | expect(result).toContain(' "gen 1"@en'); 31 | }); 32 | 33 | it('should generate description triple', () => { 34 | generalization.setDescription('gen 1 description', 'en'); 35 | 36 | const result = generateOwl(project, baseUri, prefix); 37 | expect(result).toContain(' "gen 1 description"@en'); 38 | }); 39 | 40 | it('should generate general triple', () => { 41 | const result = generateOwl(project, baseUri, prefix); 42 | expect(result).toContain(' '); 43 | }); 44 | 45 | it('should generate specific triple', () => { 46 | const result = generateOwl(project, baseUri, prefix); 47 | expect(result).toContain(' '); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/helpers.ts: -------------------------------------------------------------------------------- 1 | import { Project } from '@libs/ontouml'; 2 | import { Ontouml2Owl } from '@libs/ontouml2owl'; 3 | 4 | export function generateOwl(project: Project, baseUri: string, prefix: string, format?: string): string { 5 | const ontouml2owl = new Ontouml2Owl(project, baseUri, prefix, format || 'N-Triples'); 6 | const { result } = ontouml2owl.run(); 7 | return result; 8 | } 9 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/literals.test.ts: -------------------------------------------------------------------------------- 1 | import { Project } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe('Properties', () => { 8 | let result: String; 9 | 10 | beforeAll(() => { 11 | const project = new Project(); 12 | const model = project.createModel(); 13 | const clazz = model.createEnumeration(null, null, { id: 'c1' }); 14 | 15 | const lit1 = clazz.createLiteral(null, { id: 'l1' }); 16 | lit1.setName('rojo', 'es'); 17 | lit1.setDescription('el color rojo', 'es'); 18 | clazz.createLiteral(null, { id: 'l2' }); 19 | 20 | result = generateOwl(project, baseUri, prefix); 21 | }); 22 | 23 | it('should generate rdf:type triple', () => { 24 | expect(result).toContain(' '); 25 | }); 26 | 27 | it('should generate literal triples', () => { 28 | expect(result).toContain(' '); 29 | expect(result).toContain(' '); 30 | }); 31 | 32 | it('should generate name triple', () => { 33 | expect(result).toContain(' "rojo"@es'); 34 | }); 35 | 36 | it('should generate description triple', () => { 37 | expect(result).toContain(' "el color rojo"@es'); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/packages.test.ts: -------------------------------------------------------------------------------- 1 | import { Package, Project, Class } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe('Packages', () => { 8 | let model: Package; 9 | let result: string; 10 | 11 | beforeAll(() => { 12 | let project = new Project(); 13 | model = project.createModel({ id: 'pk1' }); 14 | model.setName('Model', 'en'); 15 | model.setDescription('The best model ever', 'en'); 16 | 17 | let class1 = model.createKind(null, { id: 'c1' }); 18 | let class2 = model.createSubkind(null, null, { id: 'c2' }); 19 | model.createMaterialRelation(class1, class2, null, { id: 'r1' }); 20 | model.createGeneralization(class1, class2, null, { id: 'g1' }); 21 | 22 | let pk2 = model.createPackage(null, { id: 'pk2' }); 23 | pk2.createKind(null, { id: 'c3' }); 24 | 25 | result = generateOwl(project, baseUri, prefix); 26 | }); 27 | 28 | it('should generate rdf:type triple', () => { 29 | expect(result).toContain(' '); 30 | }); 31 | 32 | it('should generate name triple', () => { 33 | expect(result).toContain(' "Model"@en'); 34 | }); 35 | 36 | it('should generate description triple', () => { 37 | expect(result).toContain(' "The best model ever"@en'); 38 | }); 39 | 40 | it('should generate class1 content triple', () => { 41 | expect(result).toContain( 42 | ' ' 43 | ); 44 | }); 45 | 46 | it('should generate class2 content triple', () => { 47 | expect(result).toContain( 48 | ' ' 49 | ); 50 | }); 51 | 52 | it('should generate relation content triple', () => { 53 | expect(result).toContain( 54 | ' ' 55 | ); 56 | }); 57 | 58 | it('should generate generalization content triple', () => { 59 | expect(result).toContain( 60 | ' ' 61 | ); 62 | }); 63 | 64 | it('should generate package content triple', () => { 65 | expect(result).toContain( 66 | ' ' 67 | ); 68 | }); 69 | 70 | it('should NOT generate content triple for class of a subpackage', () => { 71 | expect(result).not.toContain( 72 | ' ' 73 | ); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/path.test.ts: -------------------------------------------------------------------------------- 1 | import { Project } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe('Relation views', () => { 8 | let result: string; 9 | 10 | beforeAll(() => { 11 | const project = new Project(); 12 | 13 | const model = project.createModel({ id: 'pk1' }); 14 | const class1 = model.createKind(null, { id: 'c1' }); 15 | const class2 = model.createSubkind(null, null, { id: 'c2' }); 16 | const rel1 = model.createMaterialRelation(class1, class2, null, { id: 'r1' }); 17 | 18 | const diagram = project.createDiagram({ id: 'd1' }); 19 | const relView1 = diagram.addBinaryRelation(rel1); 20 | const path1 = relView1.shape; 21 | 22 | path1.id = 'sh1'; 23 | path1.moveTo(5, 10); 24 | path1.moveTo(15, 30); 25 | path1.moveTo(50, 100); 26 | 27 | result = generateOwl(project, baseUri, prefix); 28 | }); 29 | 30 | it('should generate rdf:type triple', () => { 31 | expect(result).toContain(' '); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/project.test.ts: -------------------------------------------------------------------------------- 1 | import { Package, Project, Class } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe('Projects', () => { 8 | let result: string; 9 | 10 | beforeAll(() => { 11 | let project = new Project({ id: 'pj1' }); 12 | project.setName('My project', 'en'); 13 | project.setDescription('The best project ever', 'en'); 14 | 15 | project.createModel({ id: 'pk1' }); 16 | project.createDiagram({ id: 'dg1' }); 17 | 18 | result = generateOwl(project, baseUri, prefix); 19 | }); 20 | 21 | it('should generate rdf:type triple', () => { 22 | expect(result).toContain(' '); 23 | }); 24 | 25 | it('should generate name triple', () => { 26 | expect(result).toContain(' "My project"@en'); 27 | }); 28 | 29 | it('should generate description triple', () => { 30 | expect(result).toContain(' "The best project ever"@en'); 31 | }); 32 | 33 | it('should generate model triple', () => { 34 | expect(result).toContain(' '); 35 | }); 36 | 37 | it('should generate diagram triple', () => { 38 | expect(result).toContain(' '); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/rectangle.test.ts: -------------------------------------------------------------------------------- 1 | import { Project } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe('Class views', () => { 8 | let result: string; 9 | 10 | beforeAll(() => { 11 | const project = new Project(); 12 | 13 | const model = project.createModel({ id: 'pk1' }); 14 | const class1 = model.createKind(null, { id: 'c1' }); 15 | 16 | const diagram = project.createDiagram({ id: 'd1' }); 17 | const shape1 = diagram.addClass(class1).shape; 18 | 19 | shape1.id = 'sh1'; 20 | shape1.width = 100; 21 | shape1.height = 80; 22 | shape1.setX(5); 23 | shape1.setY(10); 24 | 25 | result = generateOwl(project, baseUri, prefix); 26 | }); 27 | 28 | it('should generate rdf:type triple', () => { 29 | expect(result).toContain(' '); 30 | }); 31 | 32 | it('should generate height triple', () => { 33 | expect(result).toContain(' "80"^^'); 34 | }); 35 | 36 | it('should generate width triple', () => { 37 | expect(result).toContain(' "100"^^'); 38 | }); 39 | 40 | it('should generate x coordinate triple', () => { 41 | expect(result).toContain(' "5"^^'); 42 | }); 43 | 44 | it('should generate y coordinate triple', () => { 45 | expect(result).toContain(' "10"^^'); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/relation_views.test.ts: -------------------------------------------------------------------------------- 1 | import { Project } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe('Relation views', () => { 8 | let result: string; 9 | 10 | beforeAll(() => { 11 | const project = new Project(); 12 | 13 | const model = project.createModel({ id: 'pk1' }); 14 | const class1 = model.createKind(null, { id: 'c1' }); 15 | const class2 = model.createSubkind(null, null, { id: 'c2' }); 16 | const rel1 = model.createMaterialRelation(class1, class2, null, { id: 'r1' }); 17 | 18 | const diagram = project.createDiagram({ id: 'd1' }); 19 | const relView1 = diagram.addBinaryRelation(rel1); 20 | relView1.id = 'rv1'; 21 | relView1.shape.id = 'sh1'; 22 | relView1.source.id = 'cv1'; 23 | relView1.target.id = 'cv2'; 24 | 25 | result = generateOwl(project, baseUri, prefix); 26 | }); 27 | 28 | it('should generate rdf:type triple', () => { 29 | expect(result).toContain(' '); 30 | }); 31 | 32 | it('should generate "is view of" triple', () => { 33 | expect(result).toContain(' '); 34 | }); 35 | 36 | it('should generate shape triple', () => { 37 | expect(result).toContain(' '); 38 | }); 39 | 40 | it('should generate source view triple', () => { 41 | expect(result).toContain(' '); 42 | }); 43 | 44 | it('should generate target view triple', () => { 45 | expect(result).toContain(' '); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/relations.test.ts: -------------------------------------------------------------------------------- 1 | import { Package, Project, Class, Relation } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe('Relations', () => { 8 | let project: Project; 9 | let model: Package; 10 | let clazz: Class; 11 | let relation: Relation; 12 | 13 | beforeEach(() => { 14 | project = new Project(); 15 | model = project.createModel(); 16 | clazz = model.createKind(null, { id: 'c1' }); 17 | relation = model.createMaterialRelation(clazz, clazz, null, { id: 'r1' }); 18 | }); 19 | 20 | it('should generate rdf:type triple', () => { 21 | const result = generateOwl(project, baseUri, prefix); 22 | expect(result).toContain(' '); 23 | }); 24 | 25 | it('should generate stereotype triple', () => { 26 | const result = generateOwl(project, baseUri, prefix); 27 | expect(result).toContain( 28 | ' ' 29 | ); 30 | }); 31 | 32 | it('should generate name triple', () => { 33 | relation.setName('amico di', 'it'); 34 | const result = generateOwl(project, baseUri, prefix); 35 | expect(result).toContain(' "amico di"@it'); 36 | }); 37 | 38 | it('should generate description triple', () => { 39 | relation.setDescription('gli amici', 'it'); 40 | const result = generateOwl(project, baseUri, prefix); 41 | expect(result).toContain(' "gli amici"@it'); 42 | }); 43 | 44 | it('should generate isDerived triple', () => { 45 | relation.isDerived = true; 46 | const result = generateOwl(project, baseUri, prefix); 47 | expect(result).toContain(' "true"^^'); 48 | }); 49 | 50 | it('should generate sourceEnd triple', () => { 51 | relation.getSourceEnd().id = 'p1'; 52 | const result = generateOwl(project, baseUri, prefix); 53 | expect(result).toContain(' '); 54 | }); 55 | 56 | it('should generate targetEnd triple', () => { 57 | relation.getTargetEnd().id = 'p2'; 58 | const result = generateOwl(project, baseUri, prefix); 59 | expect(result).toContain(' '); 60 | }); 61 | 62 | it('should generate relationEnd triples for n-ary relations', () => { 63 | const ternary = model.createTernaryRelation([clazz, clazz, clazz], null, { id: 'r2' }); 64 | ternary.properties[0].id = 'p1'; 65 | ternary.properties[1].id = 'p2'; 66 | ternary.properties[2].id = 'p3'; 67 | const result = generateOwl(project, baseUri, prefix); 68 | expect(result).toContain(' '); 69 | expect(result).toContain(' '); 70 | expect(result).toContain(' '); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/special_characters.test.ts: -------------------------------------------------------------------------------- 1 | import { Project } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe("Special characters (~.-!$&'()*+,;=/?#@%_)", () => { 8 | let result: string; 9 | 10 | beforeEach(() => { 11 | const project = new Project(); 12 | const model = project.createModel(); 13 | model.createKind(null, { id: 'c1:' }); 14 | model.createKind(null, { id: 'c2.' }); 15 | model.createKind(null, { id: '/c3' }); 16 | model.createKind(null, { id: '#c#4' }); 17 | 18 | result = generateOwl(project, baseUri, prefix, 'Turtle'); 19 | }); 20 | 21 | it('should generate valid turtle data with class id with a colon (:)', () => { 22 | expect(result).toContain(' rdf:type ontouml:Class'); 23 | }); 24 | 25 | it('should generate valid turtle data with class id with a period (.)', () => { 26 | expect(result).toContain(' rdf:type ontouml:Class'); 27 | }); 28 | 29 | it('should generate valid turtle data with class id with a forward slash (/)', () => { 30 | expect(result).toContain(' rdf:type ontouml:Class'); 31 | }); 32 | 33 | it('should generate valid turtle data with class id with a hashtag (#)', () => { 34 | expect(result).toContain(' rdf:type ontouml:Class'); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /__tests__/libs/ontouml2owl/stereotypes.test.ts: -------------------------------------------------------------------------------- 1 | import { Project, ClassStereotype } from '@libs/ontouml'; 2 | import { generateOwl } from './helpers'; 3 | 4 | const prefix = 't'; 5 | const baseUri = 'http://test.com/'; 6 | 7 | describe('Classes', () => { 8 | let result: string; 9 | 10 | beforeEach(() => { 11 | let project = new Project(); 12 | let model = project.createModel(); 13 | model.createKind(null, { id: 'c1' }); 14 | model.createEvent(null, { id: 'c2' }); 15 | model.createClass(null, null, null, { id: 'c3' }); 16 | model.createClass(null, 'role mixin', null, { id: 'c4' }); 17 | model.createClass(null, 'role;mixin', null, { id: 'c5' }); 18 | model.createClass(null, 'role.mixin.', null, { id: 'c6' }); 19 | 20 | result = generateOwl(project, baseUri, prefix); 21 | }); 22 | 23 | it('should generate kind stereotype triple', () => { 24 | expect(result).toContain( 25 | ' ' 26 | ); 27 | }); 28 | 29 | it('should generate event stereotype triple', () => { 30 | expect(result).toContain( 31 | ' ' 32 | ); 33 | }); 34 | 35 | it('should NOT generate stereotype triple', () => { 36 | expect(result).not.toContain(' '); 37 | }); 38 | 39 | it('should handle spaces in user-defined stereotypes', () => { 40 | expect(result).toContain( 41 | ' ' 42 | ); 43 | }); 44 | 45 | it("should handle special characters (~.-!$&'()*+,;=/?#@%_) in user-defined stereotypes", () => { 46 | expect(result).toContain( 47 | ' ' 48 | ); 49 | expect(result).toContain( 50 | ' ' 51 | ); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /__tests__/libs/verification/ontouml2verification.test.ts: -------------------------------------------------------------------------------- 1 | import { Package, Project } from '@libs/ontouml'; 2 | import { OntoumlVerification } from '@libs/verification'; 3 | 4 | describe(`${OntoumlVerification.name} tests`, () => { 5 | describe(`${OntoumlVerification.name}.${OntoumlVerification.prototype.run.name}() test`, () => { 6 | it('Verification of empty projects should not throw exceptions', () => { 7 | const service = new OntoumlVerification(new Project()); 8 | expect(() => service.run()).not.toThrow(); 9 | }); 10 | 11 | it('Verification of model elements should not throw exceptions', () => { 12 | const service = new OntoumlVerification(new Package()); 13 | expect(() => service.run()).not.toThrow(); 14 | }); 15 | 16 | it('Verification of consistent models should not return issues', () => { 17 | const model = new Project().createModel(); 18 | const service = new OntoumlVerification(model); 19 | 20 | model.createGeneralization(model.createKind(), model.createSubkind()); 21 | 22 | expect(service.run().result.length).toBe(0); 23 | }); 24 | 25 | it('Verification of inconsistent models should return issues', () => { 26 | const model = new Project().createModel(); 27 | const service = new OntoumlVerification(model); 28 | 29 | model.createGeneralization(model.createSubkind(), model.createKind()); 30 | 31 | expect(service.run().result.length).toBeGreaterThan(0); 32 | }); 33 | 34 | it('Successive verifications can yield different results', () => { 35 | const model = new Project().createModel(); 36 | const service = new OntoumlVerification(model); 37 | 38 | model.createGeneralization(model.createKind(), model.createSubkind()); 39 | const issueBeforeChange = service.run(); 40 | model.createGeneralization(model.createSubkind(), model.createKind()); 41 | const issueAfterChange = service.run(); 42 | 43 | expect(issueBeforeChange.result.length).not.toBe(issueAfterChange.result.length); 44 | }); 45 | 46 | it('Verifying a fully-featured model should not throw exceptions', () => { 47 | const project = new Project(); 48 | const model = project.createModel(); 49 | 50 | project.setName('Project'); 51 | model.setName('Model'); 52 | 53 | const agent = model.createCategory('Agent'); 54 | const person = model.createKind('Person'); 55 | const organization = model.createKind('Organization'); 56 | const text = model.createDatatype('Text'); 57 | const status = model.createEnumeration('Status'); 58 | 59 | status.createLiteral('Active'); 60 | status.createLiteral('Inactive'); 61 | agent.createAttribute(text, 'name'); 62 | agent.createAttribute(status, 'status'); 63 | person.createAttribute(text, 'surname'); 64 | 65 | model.createMaterialRelation(person, organization, 'works-for'); 66 | 67 | const agentIntoPerson = model.createGeneralization(agent, person, 'agentIntoPerson'); 68 | const agentIntoOrganization = model.createGeneralization(agent, organization, 'agentIntoOrganization'); 69 | 70 | model.createPartition([agentIntoPerson, agentIntoOrganization], null, 'agentsSet'); 71 | 72 | expect(() => new OntoumlVerification(model).run()).not.toThrow(); 73 | }); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | require('./setup.ts'); 2 | 3 | // Import the rest of our application. 4 | module.exports = require('./src/index.ts'); 5 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | cache: false, 3 | testEnvironment: 'node', 4 | setupFilesAfterEnv: ["./setup.ts"], 5 | transform: { 6 | "^.+\\.(ts|tsx)?$": "ts-jest", 7 | '^.+\\.(ts|tsx)?$': 'babel-jest' 8 | }, 9 | moduleFileExtensions: [ 10 | "ts", 11 | "tsx", 12 | "js", 13 | "jsx", 14 | "json", 15 | "node", 16 | ], 17 | modulePathIgnorePatterns: ["examples"], 18 | watchPathIgnorePatterns: [ 19 | "/node_modules", 20 | ], 21 | moduleNameMapper: { 22 | "^@test-models(.*)": "/__tests__/test_models$1", 23 | "^@constants(.*)": "/src/constants$1", 24 | "^@error(.*)": "/src/error$1", 25 | "^@libs(.*)": "/src/libs$1", 26 | "^@utils(.*)": "/src/utils$1", 27 | "^@resources(.*)": "/resources$1" 28 | }, 29 | testRegex: '/__tests__/libs/.*\\.test\\.(ts|js)$', 30 | coverageDirectory: 'coverage', 31 | collectCoverageFrom: [ 32 | 'src/**/*.{ts,tsx,js,jsx}', 33 | '!src/**/*.d.ts', 34 | ] 35 | }; 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ontouml-js", 3 | "version": "0.5.0", 4 | "description": "Javascript library utility for manipulating OntoUML models.", 5 | "license": "Apache-2.0", 6 | "repository": "github:OntoUML/ontouml-js", 7 | "engines": { 8 | "node": ">= 14" 9 | }, 10 | "main": "dist/index.js", 11 | "files": [ 12 | "dist/**/*", 13 | "resources/**/*", 14 | "@types/**/*" 15 | ], 16 | "scripts": { 17 | "start": "npm-run-all -p format:watch start:watch", 18 | "start:watch": "TS_NODE_FILES=true nodemon index.ts", 19 | "format": "prettier --write \"**/*.ts\" \"**/*.json\"", 20 | "format:watch": "onchange '**/*.ts' '**/*.json' -- prettier --write {{changed}}", 21 | "clean": "rimraf coverage dist tmp", 22 | "build": "rm -rf ./dist && npm run build:js && npm run build:types && npm run build:alias", 23 | "build:js": "babel src --out-dir dist --extensions \".ts,.tsx\" --source-maps inline", 24 | "build:types": "tsc-silent -p tsconfig.release.json --suppress @", 25 | "build:alias": "tsc-alias -p tsconfig.release.json", 26 | "build:watch": "TS_NODE_FILES=true tsc -w -p tsconfig.release.json", 27 | "tsdoc": "typedoc --out tsdoc src/index.ts", 28 | "lint": "tslint -c tslint.json -p tsconfig.json 'src/**/*.ts'", 29 | "test": "jest", 30 | "test:coverage": "jest --coverage", 31 | "test:clear": "jest --clearCache", 32 | "test:watch": "jest --watch" 33 | }, 34 | "_moduleAliases": { 35 | "@test-models": "test_models", 36 | "@constants": "src/constants", 37 | "@error": "src/error", 38 | "@libs": "src/libs", 39 | "@utils": "src/utils", 40 | "@resources": "resources" 41 | }, 42 | "dependencies": { 43 | "@babel/runtime": "^7.12.13", 44 | "@types/n3": "^1.4.4", 45 | "ajv": "^7.1.1", 46 | "esm": "^3.2.25", 47 | "language-tags": "^1.0.5", 48 | "lodash": "^4.17.21", 49 | "n3": "^1.8.0", 50 | "ontouml-schema": "^0.2.4", 51 | "tslib": "~1.10.0", 52 | "uniqid": "^5.3.0", 53 | "validate.io-uri": "^1.0.0" 54 | }, 55 | "devDependencies": { 56 | "@babel/cli": "^7.12.16", 57 | "@babel/core": "^7.12.16", 58 | "@babel/plugin-proposal-class-properties": "^7.12.13", 59 | "@babel/plugin-proposal-optional-chaining": "^7.12.16", 60 | "@babel/plugin-transform-runtime": "^7.12.15", 61 | "@babel/preset-env": "^7.12.16", 62 | "@babel/preset-typescript": "^7.12.16", 63 | "@babel/register": "^7.12.13", 64 | "@types/jest": "^24.9.1", 65 | "@types/lodash": "^4.14.168", 66 | "@types/node": "^10.17.51", 67 | "babel-jest": "^24.9.0", 68 | "babel-loader": "^8.2.2", 69 | "babel-plugin-module-resolver": "^4.1.0", 70 | "dotenv": "^8.2.0", 71 | "husky": "^3.1.0", 72 | "jest": "^26.3.0", 73 | "module-alias": "^2.2.2", 74 | "nodemon": "^1.19.4", 75 | "npm-run-all": "^4.1.5", 76 | "onchange": "^6.1.1", 77 | "prettier": "^2.2.1", 78 | "rimraf": "^3.0.2", 79 | "ts-jest": "^24.3.0", 80 | "ts-node": "^8.10.2", 81 | "tsc-alias": "^1.3.5", 82 | "tsc-silent": "^1.2.1", 83 | "tslint": "^5.20.1", 84 | "tslint-config-prettier": "^1.18.0", 85 | "tslint-microsoft-contrib": "^6.2.0", 86 | "tsutils": "^3.20.0", 87 | "typedoc": "^0.20.28", 88 | "typescript": "^4.1" 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /resources/howto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OntoUML/ontouml-js/bfb3fbe60965fb2469cb234f85a8880b6a882696/resources/howto.png -------------------------------------------------------------------------------- /resources/schemas/class.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/Class", 4 | "description": "An object representing a class element. Mandatory fields: constant \"type\": \"Class\", \"id\", \"name\", \"stereotype\", \"properties\", \"propertyAssignments\", \"isAbstract\", \"isDerived\", \"isExtensional\", \"isPowertype\", \"order\", \"natures\". Additional fields NOT allowed.", 5 | "type": "object", 6 | "properties": { 7 | "type": { 8 | "const": "Class" 9 | }, 10 | "id": { 11 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 12 | }, 13 | "name": { 14 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 15 | }, 16 | "description": { 17 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 18 | }, 19 | "propertyAssignments": { 20 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#propertyAssignments" 21 | }, 22 | "stereotype": { 23 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#stereotype" 24 | }, 25 | "isAbstract": { 26 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#isAbstract" 27 | }, 28 | "isDerived": { 29 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#isDerived" 30 | }, 31 | "properties": { 32 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#properties" 33 | }, 34 | "literals": { 35 | "oneOf": [ 36 | { 37 | "type": "array", 38 | "items": { 39 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/Literal" 40 | } 41 | }, 42 | { 43 | "type": "null" 44 | } 45 | ] 46 | }, 47 | "restrictedTo": { 48 | "description": "A nullable array of unique enumerated strings that represents the allowed (possible) ontological natures of the class's instances.", 49 | "oneOf": [ 50 | { 51 | "type": "null" 52 | }, 53 | { 54 | "type": "array", 55 | "uniqueItems": true, 56 | "items": { 57 | "type": "string" 58 | } 59 | } 60 | ] 61 | }, 62 | "isExtensional": { 63 | "description": "A boolean field that captures if a class decorated as «collective» is extensionally defined (i.e., it's parts cannot change).", 64 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableBoolean" 65 | }, 66 | "isPowertype": { 67 | "description": "A boolean field that captures if a class decorated as «type» represents a powertype.", 68 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableBoolean" 69 | }, 70 | "order": { 71 | "description": "A string field that captures the type-order of a class decorated as «type». This field supports the representation of second-order types or greater, thus its minimum value is \"2\". This field must be set to \"*\" for orderless types.", 72 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableString" 73 | } 74 | }, 75 | "additionalProperties": true, 76 | "required": ["type", "id"] 77 | } 78 | -------------------------------------------------------------------------------- /resources/schemas/class_view.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/ClassView", 4 | "type": "object", 5 | "properties": { 6 | "type": { 7 | "const": "ClassView" 8 | }, 9 | "id": { 10 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 11 | }, 12 | "name": { 13 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 14 | }, 15 | "description": { 16 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 17 | }, 18 | "modelElement": { 19 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 20 | }, 21 | "shape": { 22 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/RectangleShape" 23 | } 24 | }, 25 | "additionalProperties": true, 26 | "required": ["type", "id", "modelElement"] 27 | } 28 | -------------------------------------------------------------------------------- /resources/schemas/diagram.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/Diagram", 4 | "description": "An array containing the values defined for an enumeration. Should only be used if the class is stereotyped as <>, otherwise, the value of this field should be null.", 5 | "type": "object", 6 | "properties": { 7 | "type": { 8 | "const": "Diagram" 9 | }, 10 | "id": { 11 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 12 | }, 13 | "name": { 14 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 15 | }, 16 | "description": { 17 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 18 | }, 19 | "contents": { 20 | "oneOf": [ 21 | { 22 | "type": "null" 23 | }, 24 | { 25 | "type": "array", 26 | "items": { 27 | "oneOf": [ 28 | { 29 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/ClassView" 30 | }, 31 | { 32 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/RelationView" 33 | }, 34 | { 35 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/GeneralizationView" 36 | }, 37 | { 38 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/GeneralizationSetView" 39 | }, 40 | { 41 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/PackageView" 42 | } 43 | ] 44 | } 45 | } 46 | ] 47 | }, 48 | "owner": { 49 | "oneOf": [ 50 | { 51 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 52 | } 53 | ] 54 | } 55 | }, 56 | "additionalProperties": true, 57 | "required": ["type", "id"] 58 | } 59 | -------------------------------------------------------------------------------- /resources/schemas/generalization.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/Generalization", 4 | "description": "An object representing a generalization element. Mandatory fields: constant \"type\": \"Generalization\", \"id\", \"name\", \"general\", \"specific\", \"propertyAssignments\". Additional fields NOT allowed.", 5 | "type": "object", 6 | "properties": { 7 | "type": { 8 | "const": "Generalization" 9 | }, 10 | "id": { 11 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 12 | }, 13 | "name": { 14 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 15 | }, 16 | "description": { 17 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 18 | }, 19 | "propertyAssignments": { 20 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#propertyAssignments" 21 | }, 22 | "general": { 23 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 24 | }, 25 | "specific": { 26 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 27 | } 28 | }, 29 | "additionalProperties": true, 30 | "required": ["type", "id", "general", "specific"] 31 | } 32 | -------------------------------------------------------------------------------- /resources/schemas/generalization_set.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/GeneralizationSet", 4 | "description": "An object representing a generalization set element. Mandatory fields: constant \"type\": \"GeneralizationSet\", \"id\", \"name\", \"isDisjoint\", \"isComplete\", \"categorizer\", \"generalizations\", \"propertyAssignments\". Additional fields NOT allowed.", 5 | "type": "object", 6 | "properties": { 7 | "type": { 8 | "const": "GeneralizationSet" 9 | }, 10 | "id": { 11 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 12 | }, 13 | "name": { 14 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 15 | }, 16 | "description": { 17 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 18 | }, 19 | "propertyAssignments": { 20 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#propertyAssignments" 21 | }, 22 | "isDisjoint": { 23 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableBoolean" 24 | }, 25 | "isComplete": { 26 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableBoolean" 27 | }, 28 | "categorizer": { 29 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 30 | }, 31 | "generalizations": { 32 | "oneOf": [ 33 | { 34 | "type": "array", 35 | "items": { 36 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 37 | } 38 | }, 39 | { 40 | "type": "null" 41 | } 42 | ] 43 | } 44 | }, 45 | "additionalProperties": true, 46 | "required": ["type", "id"] 47 | } 48 | -------------------------------------------------------------------------------- /resources/schemas/generalization_set_view.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/GeneralizationSetView", 4 | "type": "object", 5 | "properties": { 6 | "type": { 7 | "const": "GeneralizationSetView" 8 | }, 9 | "id": { 10 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 11 | }, 12 | "name": { 13 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 14 | }, 15 | "description": { 16 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 17 | }, 18 | "modelElement": { 19 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 20 | }, 21 | "shape": { 22 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/TextShape" 23 | } 24 | }, 25 | "additionalProperties": true, 26 | "required": ["type", "id", "modelElement"] 27 | } 28 | -------------------------------------------------------------------------------- /resources/schemas/generalization_view.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/GeneralizationView", 4 | "type": "object", 5 | "properties": { 6 | "type": { 7 | "const": "GeneralizationView" 8 | }, 9 | "id": { 10 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 11 | }, 12 | "name": { 13 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 14 | }, 15 | "description": { 16 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 17 | }, 18 | "modelElement": { 19 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 20 | }, 21 | "source": { 22 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 23 | }, 24 | "target": { 25 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 26 | }, 27 | "shape": { 28 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/PathShape" 29 | } 30 | }, 31 | "additionalProperties": true, 32 | "required": ["type", "id", "modelElement", "source", "target"] 33 | } 34 | -------------------------------------------------------------------------------- /resources/schemas/literal.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/Literal", 4 | "description": "An array containing the values defined for an enumeration. Should only be used if the class is stereotyped as <>, otherwise, the value of this field should be null.", 5 | "type": "object", 6 | "properties": { 7 | "type": { 8 | "const": "Literal" 9 | }, 10 | "id": { 11 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 12 | }, 13 | "name": { 14 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 15 | }, 16 | "description": { 17 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 18 | }, 19 | "propertyAssignments": { 20 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#propertyAssignments" 21 | } 22 | }, 23 | "additionalProperties": true, 24 | "required": ["type", "id"] 25 | } 26 | -------------------------------------------------------------------------------- /resources/schemas/package.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/Package", 4 | "description": "An object representing a package element. Mandatory fields: constant \"type\": \"Package\", \"id\", \"name\", \"elements\", \"propertyAssignments\". Additional fields NOT allowed.", 5 | "type": "object", 6 | "properties": { 7 | "type": { 8 | "const": "Package" 9 | }, 10 | "id": { 11 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 12 | }, 13 | "name": { 14 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 15 | }, 16 | "description": { 17 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 18 | }, 19 | "propertyAssignments": { 20 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#propertyAssignments" 21 | }, 22 | "contents": { 23 | "oneOf": [ 24 | { 25 | "type": "null" 26 | }, 27 | { 28 | "type": "array", 29 | "items": { 30 | "oneOf": [ 31 | { 32 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/Package" 33 | }, 34 | { 35 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/Class" 36 | }, 37 | { 38 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/Relation" 39 | }, 40 | { 41 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/GeneralizationSet" 42 | }, 43 | { 44 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/Generalization" 45 | } 46 | ] 47 | } 48 | } 49 | ] 50 | } 51 | }, 52 | "additionalProperties": true, 53 | "required": ["type", "id"] 54 | } 55 | -------------------------------------------------------------------------------- /resources/schemas/package_view.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/PackageView", 4 | "type": "object", 5 | "properties": { 6 | "type": { 7 | "const": "PackageView" 8 | }, 9 | "id": { 10 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 11 | }, 12 | "name": { 13 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 14 | }, 15 | "description": { 16 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 17 | }, 18 | "modelElement": { 19 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 20 | }, 21 | "shape": { 22 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/RectangleShape" 23 | } 24 | }, 25 | "additionalProperties": true, 26 | "required": ["type", "id", "modelElement"] 27 | } 28 | -------------------------------------------------------------------------------- /resources/schemas/path_shape.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/PathShape", 4 | "type": "object", 5 | "properties": { 6 | "type": { 7 | "const": "Path" 8 | }, 9 | "id": { 10 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 11 | }, 12 | "name": { 13 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 14 | }, 15 | "description": { 16 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 17 | }, 18 | "points": { 19 | "oneOf": [ 20 | { 21 | "type": "null" 22 | }, 23 | { 24 | "type": "array", 25 | "items": { 26 | "type": "object", 27 | "properties": { 28 | "x": { 29 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableNatural" 30 | }, 31 | "y": { 32 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableNatural" 33 | } 34 | }, 35 | "additionalProperties": true, 36 | "required": ["x", "y"] 37 | } 38 | } 39 | ] 40 | } 41 | }, 42 | "additionalProperties": true, 43 | "required": ["type", "id"] 44 | } 45 | -------------------------------------------------------------------------------- /resources/schemas/project.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/Project", 4 | "title": "Project", 5 | "description": "A project of an ontology in OntoUML 2, which may contain both model and diagrammatic data.", 6 | "type": "object", 7 | "properties": { 8 | "type": { 9 | "const": "Project" 10 | }, 11 | "id": { 12 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 13 | }, 14 | "name": { 15 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 16 | }, 17 | "description": { 18 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 19 | }, 20 | "model": { 21 | "oneOf": [ 22 | { 23 | "type": "null" 24 | }, 25 | { 26 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/Package" 27 | } 28 | ] 29 | }, 30 | "diagrams": { 31 | "oneOf": [ 32 | { 33 | "type": "null" 34 | }, 35 | { 36 | "type": "array" 37 | } 38 | ] 39 | } 40 | }, 41 | "additionalProperties": true, 42 | "required": ["type", "id"] 43 | } 44 | -------------------------------------------------------------------------------- /resources/schemas/property.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/Property", 4 | "description": "An object representing a property element. This represents properties exhibited by instances of classes, relations and derivation relations, where in the first case properties are analougous to attrbutes while in the second and third cases properties are analogous to association ends. Mandatory fields: constant \"type\": \"Property\", \"id\", \"name\" \"cardinality\", \"stereotype\", \"propertyAssignments\", \"subsettedProperties\", \"redefinedProperties\", \"aggregationKind\", \"isDerived\", \"isOrdered\", \"isReadOnly\". Additional fields NOT allowed.", 5 | "type": "object", 6 | "properties": { 7 | "type": { 8 | "const": "Property" 9 | }, 10 | "id": { 11 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 12 | }, 13 | "name": { 14 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 15 | }, 16 | "description": { 17 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 18 | }, 19 | "propertyAssignments": { 20 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#propertyAssignments" 21 | }, 22 | "stereotype": { 23 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#stereotype" 24 | }, 25 | "aggregationKind": { 26 | "oneOf": [ 27 | { 28 | "type": "string", 29 | "enum": ["NONE", "SHARED", "COMPOSITE"] 30 | }, 31 | { 32 | "type": "null" 33 | } 34 | ] 35 | }, 36 | "cardinality": { 37 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableString" 38 | }, 39 | "isDerived": { 40 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableBoolean" 41 | }, 42 | "isOrdered": { 43 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableBoolean" 44 | }, 45 | "isReadOnly": { 46 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableBoolean" 47 | }, 48 | "propertyType": { 49 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 50 | }, 51 | "redefinedProperties": { 52 | "oneOf": [ 53 | { 54 | "type": "array", 55 | "uniqueItems": true, 56 | "items": { 57 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 58 | } 59 | }, 60 | { 61 | "type": "null" 62 | } 63 | ] 64 | }, 65 | "subsettedProperties": { 66 | "oneOf": [ 67 | { 68 | "type": "array", 69 | "uniqueItems": true, 70 | "items": { 71 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 72 | } 73 | }, 74 | { 75 | "type": "null" 76 | } 77 | ] 78 | } 79 | }, 80 | "additionalProperties": true, 81 | "required": ["type", "id"] 82 | } 83 | -------------------------------------------------------------------------------- /resources/schemas/rectangle_shape.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/RectangleShape", 4 | "type": "object", 5 | "properties": { 6 | "type": { 7 | "const": "Rectangle" 8 | }, 9 | "id": { 10 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 11 | }, 12 | "name": { 13 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 14 | }, 15 | "description": { 16 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 17 | }, 18 | "x": { 19 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableNatural" 20 | }, 21 | "y": { 22 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableNatural" 23 | }, 24 | "width": { 25 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableNatural" 26 | }, 27 | "height": { 28 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableNatural" 29 | } 30 | }, 31 | "additionalProperties": true, 32 | "required": ["type", "id"] 33 | } 34 | -------------------------------------------------------------------------------- /resources/schemas/relation.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/Relation", 4 | "description": "An object representing an relation element. Mandatory fields: constant \"type\": \"Class\", \"id\", \"name\", \"stereotype\", \"properties\", \"propertyAssignments\". The \"properties\" array must have at least two items and is not nullable. The order of these items represents their position on a equivalent predicate, e.g., in the ternary relation \"buys-product-from(buyer,product,seller)\", the order of items representing these entities must follow the order \"buyer\" (in properties[0]), \"product\" (in properties[1]), and \"seller\" (in properties[2]). Relation elements are also used to represent derivation relations, in which case they must contain the stereotype \"derivation\" and have only 2 properties, the first being a Relation element and the second a Class element. Additional fields NOT allowed. Ordered properties.", 5 | "type": "object", 6 | "properties": { 7 | "type": { 8 | "const": "Relation" 9 | }, 10 | "id": { 11 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 12 | }, 13 | "name": { 14 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 15 | }, 16 | "description": { 17 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 18 | }, 19 | "propertyAssignments": { 20 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#propertyAssignments" 21 | }, 22 | "stereotype": { 23 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#stereotype" 24 | }, 25 | "isAbstract": { 26 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#isAbstract" 27 | }, 28 | "isDerived": { 29 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#isDerived" 30 | }, 31 | "properties": { 32 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#properties" 33 | } 34 | }, 35 | "additionalProperties": true, 36 | "required": ["type", "id"] 37 | } 38 | -------------------------------------------------------------------------------- /resources/schemas/relation_view.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/RelationView", 4 | "type": "object", 5 | "properties": { 6 | "type": { 7 | "const": "RelationView" 8 | }, 9 | "id": { 10 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 11 | }, 12 | "name": { 13 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 14 | }, 15 | "description": { 16 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 17 | }, 18 | "modelElement": { 19 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 20 | }, 21 | "source": { 22 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 23 | }, 24 | "target": { 25 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#reference" 26 | }, 27 | "shape": { 28 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/PathShape" 29 | } 30 | }, 31 | "additionalProperties": true, 32 | "required": ["type", "id", "modelElement", "source", "target"] 33 | } 34 | -------------------------------------------------------------------------------- /resources/schemas/text_shape.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://ontouml.org/ontouml-schema/2021-02-26/TextShape", 4 | "type": "object", 5 | "properties": { 6 | "type": { 7 | "const": "Text" 8 | }, 9 | "id": { 10 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#id" 11 | }, 12 | "name": { 13 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 14 | }, 15 | "description": { 16 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#text" 17 | }, 18 | "x": { 19 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableNatural" 20 | }, 21 | "y": { 22 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableNatural" 23 | }, 24 | "width": { 25 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableNatural" 26 | }, 27 | "height": { 28 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableNatural" 29 | }, 30 | "value": { 31 | "$ref": "https://ontouml.org/ontouml-schema/2021-02-26/definitions#nullableString" 32 | } 33 | }, 34 | "additionalProperties": true, 35 | "required": ["type", "id"] 36 | } 37 | -------------------------------------------------------------------------------- /setup.ts: -------------------------------------------------------------------------------- 1 | require('module-alias/register'); 2 | 3 | const dotenv = require('dotenv'); 4 | dotenv.config(); 5 | 6 | // Transpile all code following this line with babel and use '@babel/preset-env' (aka ES6) preset. 7 | require('@babel/register')({ 8 | extensions: ['.ts'], 9 | presets: ['@babel/preset-env', '@babel/preset-typescript'], 10 | plugins: ['@babel/plugin-transform-runtime'] 11 | }); 12 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './libs'; 2 | export { Modularizer } from './libs/complexity'; 3 | export * from './libs/ontouml'; 4 | export * from './libs'; 5 | export * from './libs/ontouml2owl'; 6 | export { Ontouml2Db, Ontouml2DbOptions } from './libs/ontouml2db'; 7 | export { Ontouml2Gufo, Ontouml2GufoOptions } from './libs/ontouml2gufo'; 8 | export { OntoumlVerification, VerificationIssue, VerificationIssueCode } from './libs/verification'; 9 | -------------------------------------------------------------------------------- /src/libs/abstraction/abstraction.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Package, 3 | Class, 4 | GeneralizationSet, 5 | Generalization, 6 | Relation, 7 | ModelElement, 8 | Diagram 9 | } from '@libs/ontouml'; 10 | import { uniqBy } from 'lodash'; 11 | 12 | export class Abstraction { 13 | name: string; 14 | classes: Class[]; 15 | relations: Relation[]; 16 | generalizations: Generalization[]; 17 | generalizationSets: GeneralizationSet[]; 18 | 19 | constructor(name: string) { 20 | this.name = name; 21 | this.classes = []; 22 | this.relations = []; 23 | this.generalizations = []; 24 | this.generalizationSets = []; 25 | } 26 | 27 | createDiagram(owner: Package): Diagram { 28 | let diagram = new Diagram(); 29 | diagram.setName(this.name); 30 | diagram.owner = owner; 31 | 32 | let pos: number = 40; 33 | this?.classes.forEach(_class => { 34 | let view = diagram.addClass(_class); 35 | view.setX(pos); 36 | view.setY(40); 37 | pos += 120; 38 | }); 39 | 40 | diagram.addModelElements(this.relations); 41 | diagram.addModelElements(this.generalizations); 42 | diagram.addModelElements(this.generalizationSets); 43 | 44 | return diagram; 45 | } 46 | 47 | addClasses(classes: Class[]) { 48 | this.classes = this.classes.concat(classes); 49 | } 50 | 51 | containsRelation(relation: Relation): boolean { 52 | return this.relations.findIndex(r => r.id === relation.id) >= 0; 53 | } 54 | 55 | addRelations(relations: Relation[]) { 56 | this.relations = this.relations.concat(relations); 57 | } 58 | 59 | addGeneralizations(generalizations: Generalization[]) { 60 | this.generalizations = this.generalizations.concat(generalizations); 61 | } 62 | 63 | addGeneralizationSets(generalizationSets: GeneralizationSet[]) { 64 | this.generalizationSets = this.generalizationSets.concat(generalizationSets); 65 | } 66 | 67 | removeDuplicates() { 68 | this.classes = Abstraction.removeDuplicatesArray(this.classes); 69 | this.relations = Abstraction.removeDuplicatesArray(this.relations); 70 | this.generalizations = Abstraction.removeDuplicatesArray(this.generalizations); 71 | this.generalizationSets = Abstraction.removeDuplicatesArray(this.generalizationSets); 72 | } 73 | 74 | static removeDuplicatesArray(elements: T[]): T[] { 75 | return uniqBy(elements, 'id'); 76 | } 77 | 78 | addAll(cluster: Abstraction): boolean { 79 | if (!cluster) return false; 80 | 81 | this.addClasses(cluster.classes); 82 | this.addRelations(cluster.relations); 83 | this.addGeneralizations(cluster.generalizations); 84 | this.addGeneralizationSets(cluster.generalizationSets); 85 | 86 | this.removeDuplicates(); 87 | return true; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/libs/abstraction/index.ts: -------------------------------------------------------------------------------- 1 | export * from './abstractor'; 2 | export * from './abstraction'; -------------------------------------------------------------------------------- /src/libs/complexity/index.ts: -------------------------------------------------------------------------------- 1 | export * from './modularizer'; 2 | export * from './module'; 3 | export * from './viewpoint_extractor'; 4 | -------------------------------------------------------------------------------- /src/libs/complexity/module.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Package, 3 | Class, 4 | GeneralizationSet, 5 | Generalization, 6 | Relation, 7 | ModelElement, 8 | Diagram 9 | } from '@libs/ontouml'; 10 | import { uniqBy } from 'lodash'; 11 | 12 | export class Module { 13 | name: string; 14 | classes: Class[]; 15 | relations: Relation[]; 16 | generalizations: Generalization[]; 17 | generalizationSets: GeneralizationSet[]; 18 | 19 | constructor(name: string) { 20 | this.name = name; 21 | this.classes = []; 22 | this.relations = []; 23 | this.generalizations = []; 24 | this.generalizationSets = []; 25 | } 26 | 27 | createDiagram(owner: Package): Diagram { 28 | let diagram = new Diagram(); 29 | diagram.setName(this.name); 30 | diagram.owner = owner; 31 | 32 | let pos: number = 40; 33 | this?.classes.forEach(_class => { 34 | let view = diagram.addClass(_class); 35 | view.setX(pos); 36 | view.setY(40); 37 | pos += 120; 38 | }); 39 | 40 | diagram.addModelElements(this.relations); 41 | diagram.addModelElements(this.generalizations); 42 | diagram.addModelElements(this.generalizationSets); 43 | 44 | return diagram; 45 | } 46 | 47 | addClasses(classes: Class[]) { 48 | this.classes = this.classes.concat(classes); 49 | } 50 | 51 | containsRelation(relation: Relation): boolean { 52 | return this.relations.findIndex(r => r.id === relation.id) >= 0; 53 | } 54 | 55 | addRelations(relations: Relation[]) { 56 | this.relations = this.relations.concat(relations); 57 | } 58 | 59 | addGeneralizations(generalizations: Generalization[]) { 60 | this.generalizations = this.generalizations.concat(generalizations); 61 | } 62 | 63 | addGeneralizationSets(generalizationSets: GeneralizationSet[]) { 64 | this.generalizationSets = this.generalizationSets.concat(generalizationSets); 65 | } 66 | 67 | removeDuplicates() { 68 | this.classes = Module.removeDuplicatesArray(this.classes); 69 | this.relations = Module.removeDuplicatesArray(this.relations); 70 | this.generalizations = Module.removeDuplicatesArray(this.generalizations); 71 | this.generalizationSets = Module.removeDuplicatesArray(this.generalizationSets); 72 | } 73 | 74 | static removeDuplicatesArray(elements: T[]): T[] { 75 | return uniqBy(elements, 'id'); 76 | } 77 | 78 | addAll(cluster: Module): boolean { 79 | if (!cluster) return false; 80 | 81 | this.addClasses(cluster.classes); 82 | this.addRelations(cluster.relations); 83 | this.addGeneralizations(cluster.generalizations); 84 | this.addGeneralizationSets(cluster.generalizationSets); 85 | 86 | this.removeDuplicates(); 87 | return true; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/libs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './service'; 2 | export * from './service_options'; 3 | export * from './service_issue'; 4 | export * from './service_issue_severity'; 5 | -------------------------------------------------------------------------------- /src/libs/ontouml/index.ts: -------------------------------------------------------------------------------- 1 | export * from './utils'; 2 | export * from './model/cardinality'; 3 | export * from './ontouml_type'; 4 | export * from './multilingual_text'; 5 | export * from './ontouml_element'; 6 | export * from './model/model_element'; 7 | export * from './model/literal'; 8 | export * from './model/decoratable'; 9 | export * from './model/classifier'; 10 | export * from './model/class'; 11 | export * from './model/generalization'; 12 | export * from './model/generalization_set'; 13 | export * from './container_utils'; 14 | export * from './model/model_element_container'; 15 | export * from './project'; 16 | export * from './model/package'; 17 | export * from './model/property'; 18 | export * from './model/relation'; 19 | export * from './model/stereotypes'; 20 | export * from './model/natures'; 21 | export * from './view/point'; 22 | export * from './view/diagram_element'; 23 | export * from './view/shape'; 24 | export * from './view/rectangular_shape'; 25 | export * from './view/rectangle'; 26 | export * from './view/text'; 27 | export * from './view/path'; 28 | export * from './view/element_view'; 29 | export * from './view/node_view'; 30 | export * from './view/package_view'; 31 | export * from './view/generalization_set_view'; 32 | export * from './view/class_view'; 33 | export * from './view/connector_view'; 34 | export * from './view/generalization_view'; 35 | export * from './view/relation_view'; 36 | export * from './view/diagram'; 37 | export * from './serialization'; 38 | -------------------------------------------------------------------------------- /src/libs/ontouml/model/decoratable.ts: -------------------------------------------------------------------------------- 1 | import { ModelElement, Stereotype } from '..'; 2 | 3 | export abstract class Decoratable extends ModelElement { 4 | stereotype: S; 5 | 6 | constructor(type: string, base: Partial>) { 7 | super(type, base); 8 | 9 | this.stereotype = base?.stereotype || null; 10 | } 11 | 12 | abstract getAllowedStereotypes(): S[]; 13 | 14 | isStereotypeValid(allowsNone: boolean = false): boolean { 15 | return this.getAllowedStereotypes().includes(this.stereotype) || (!this.stereotype && allowsNone); 16 | } 17 | 18 | /** Checks if `this.stereotype` is contained in the set of values in `stereotypes`. 19 | * 20 | * @throws error when the class has multiple stereotypes 21 | * */ 22 | hasAnyStereotype(stereotypes: S | S[]): boolean { 23 | return Array.isArray(stereotypes) ? stereotypes.includes(this.stereotype) : this.stereotype === stereotypes; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/libs/ontouml/model/literal.ts: -------------------------------------------------------------------------------- 1 | import { OntoumlElement, ModelElement, OntoumlType } from '..'; 2 | 3 | export class Literal extends ModelElement { 4 | constructor(base?: Partial) { 5 | super(OntoumlType.LITERAL_TYPE, base); 6 | } 7 | 8 | getContents(): OntoumlElement[] { 9 | return []; 10 | } 11 | 12 | clone(): Literal { 13 | return new Literal(this); 14 | } 15 | 16 | replace(originalElement: ModelElement, newElement: ModelElement): void { 17 | if (this.container === originalElement) { 18 | this.container = newElement; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/libs/ontouml/model/model_element.ts: -------------------------------------------------------------------------------- 1 | import { OntoumlElement, Package } from '..'; 2 | 3 | export abstract class ModelElement extends OntoumlElement { 4 | propertyAssignments: object; 5 | 6 | constructor(type: string, base?: Partial) { 7 | super(type, base); 8 | 9 | this.propertyAssignments = base?.propertyAssignments || {}; 10 | } 11 | 12 | toJSON(): any { 13 | const modelElementSerialization = { 14 | propertyAssignments: null 15 | }; 16 | 17 | Object.assign(modelElementSerialization, super.toJSON()); 18 | 19 | return modelElementSerialization; 20 | } 21 | 22 | /** Clones the model element and all its contents. Replaces all references to 23 | * original contents with references to cloned elements. */ 24 | abstract clone(): ModelElement; 25 | 26 | // TODO: replace references in property assignments 27 | /** Replaces references to `originalElement` with references to `newElement`. 28 | * Designed to be used within clone(). */ 29 | abstract replace(originalElement: ModelElement, newElement: ModelElement): void; 30 | 31 | lock(): void { 32 | throw new Error('Method unimplemented!'); 33 | } 34 | 35 | unlock(): void { 36 | throw new Error('Method unimplemented!'); 37 | } 38 | 39 | isLocked(): boolean { 40 | throw new Error('Method unimplemented!'); 41 | } 42 | 43 | /** 44 | * Returns outermost package container of a model element which can either 45 | * 'model' package of a project, a package without a container, or null. This 46 | * is intended to support searches for other model elements within the same 47 | * context, regardless of the presence of a container project. 48 | */ 49 | getModelOrRootPackage(): Package { 50 | if (this.project) { 51 | return this.project.model; 52 | } 53 | 54 | let packageReference = this.container; 55 | 56 | while (packageReference && packageReference.container) { 57 | packageReference = packageReference.container; 58 | } 59 | 60 | if (packageReference instanceof Package) { 61 | return packageReference; 62 | } else if (this instanceof Package) { 63 | return this; 64 | } else { 65 | return null; 66 | } 67 | } 68 | 69 | resolveReferences(_elementReferenceMap: Map): void { 70 | // TODO: resolve references within propertyAssignments 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/libs/ontouml/model/model_element_container.ts: -------------------------------------------------------------------------------- 1 | import { 2 | OntoumlElement, 3 | OntoumlType, 4 | Class, 5 | ClassStereotype, 6 | OntologicalNature, 7 | PropertyStereotype, 8 | RelationStereotype, 9 | Generalization, 10 | GeneralizationSet, 11 | Literal, 12 | ModelElement, 13 | Package, 14 | Property, 15 | Relation 16 | } from '..'; 17 | 18 | export interface ModelElementContainer { 19 | getElementById(id: String): OntoumlElement; 20 | getClassById(id: String): Class; 21 | getRelationById(id: String): Relation; 22 | getPropertyById(id: String): Property; 23 | getGeneralizationById(id: String): Generalization; 24 | getGeneralizationSetById(id: String): GeneralizationSet; 25 | getPackageById(id: String): Package; 26 | getAllPackages(): Package[]; 27 | getAllClasses(): Class[]; 28 | getAllEnumerations(): Class[]; 29 | getAllProperties(): Property[]; 30 | getAllAttributes(): Property[]; 31 | getAllLiterals(): Literal[]; 32 | getAllRelations(): Relation[]; 33 | getAllRelationEnds(): Property[]; 34 | getAllGeneralizations(): Generalization[]; 35 | getAllGeneralizationSets(): GeneralizationSet[]; 36 | getAllModelElements(): ModelElement[]; 37 | getAllContentsByType(type: OntoumlType | OntoumlType[]): OntoumlElement[]; 38 | getAllAttributesByStereotype(stereotype: PropertyStereotype | PropertyStereotype[]): Property[]; 39 | getAllClassesByStereotype(stereotype: ClassStereotype | ClassStereotype[]): Class[]; 40 | getAllRelationsByStereotype(stereotype: RelationStereotype | RelationStereotype[]): Relation[]; 41 | getAllClassesWithRestrictedToContainedIn(nature: OntologicalNature | OntologicalNature[]): Class[]; 42 | getClassesWithTypeStereotype(): Class[]; 43 | getClassesWithHistoricalRoleStereotype(): Class[]; 44 | getClassesWithHistoricalRoleMixinStereotype(): Class[]; 45 | getClassesWithEventStereotype(): Class[]; 46 | getClassesWithSituationStereotype(): Class[]; 47 | getClassesWithCategoryStereotype(): Class[]; 48 | getClassesWithMixinStereotype(): Class[]; 49 | getClassesWithRoleMixinStereotype(): Class[]; 50 | getClassesWithPhaseMixinStereotype(): Class[]; 51 | getClassesWithKindStereotype(): Class[]; 52 | getClassesWithCollectiveStereotype(): Class[]; 53 | getClassesWithQuantityStereotype(): Class[]; 54 | getClassesWithRelatorStereotype(): Class[]; 55 | getClassesWithQualityStereotype(): Class[]; 56 | getClassesWithModeStereotype(): Class[]; 57 | getClassesWithSubkindStereotype(): Class[]; 58 | getClassesWithRoleStereotype(): Class[]; 59 | getClassesWithPhaseStereotype(): Class[]; 60 | getClassesWithEnumerationStereotype(): Class[]; 61 | getClassesWithDatatypeStereotype(): Class[]; 62 | getClassesWithAbstractStereotype(): Class[]; 63 | getClassesRestrictedToFunctionalComplex(): Class[]; 64 | getClassesRestrictedToCollective(): Class[]; 65 | getClassesRestrictedToQuantity(): Class[]; 66 | getClassesRestrictedToMode(): Class[]; 67 | getClassesRestrictedToIntrinsicMode(): Class[]; 68 | getClassesRestrictedToExtrinsicMode(): Class[]; 69 | getClassesRestrictedToQuality(): Class[]; 70 | getClassesRestrictedToRelator(): Class[]; 71 | } 72 | -------------------------------------------------------------------------------- /src/libs/ontouml/model/natures.ts: -------------------------------------------------------------------------------- 1 | export enum OntologicalNature { 2 | functional_complex = 'functional-complex', 3 | collective = 'collective', 4 | quantity = 'quantity', 5 | relator = 'relator', 6 | intrinsic_mode = 'intrinsic-mode', 7 | extrinsic_mode = 'extrinsic-mode', 8 | quality = 'quality', 9 | event = 'event', 10 | situation = 'situation', 11 | type = 'type', 12 | abstract = 'abstract' 13 | } 14 | 15 | const Natures = [ 16 | OntologicalNature.functional_complex, 17 | OntologicalNature.collective, 18 | OntologicalNature.quantity, 19 | OntologicalNature.intrinsic_mode, 20 | OntologicalNature.extrinsic_mode, 21 | OntologicalNature.quality, 22 | OntologicalNature.relator, 23 | OntologicalNature.event, 24 | OntologicalNature.situation, 25 | OntologicalNature.type, 26 | OntologicalNature.abstract 27 | ]; 28 | 29 | const EndurantNatures = [ 30 | OntologicalNature.functional_complex, 31 | OntologicalNature.collective, 32 | OntologicalNature.quantity, 33 | OntologicalNature.intrinsic_mode, 34 | OntologicalNature.extrinsic_mode, 35 | OntologicalNature.quality, 36 | OntologicalNature.relator 37 | ]; 38 | 39 | const SubstantialNatures = [OntologicalNature.functional_complex, OntologicalNature.collective, OntologicalNature.quantity]; 40 | 41 | const MomentNatures = [ 42 | OntologicalNature.intrinsic_mode, 43 | OntologicalNature.extrinsic_mode, 44 | OntologicalNature.quality, 45 | OntologicalNature.relator 46 | ]; 47 | 48 | const IntrinsicMomentNatures = [OntologicalNature.intrinsic_mode, OntologicalNature.quality]; 49 | 50 | const ExtrinsicMomentNatures = [OntologicalNature.extrinsic_mode, OntologicalNature.relator]; 51 | 52 | const naturesArrays = [ 53 | Natures, 54 | EndurantNatures, 55 | SubstantialNatures, 56 | MomentNatures, 57 | IntrinsicMomentNatures, 58 | ExtrinsicMomentNatures 59 | ]; 60 | naturesArrays.forEach((array: OntologicalNature[]) => Object.freeze(array)); 61 | 62 | export const natureUtils = { 63 | Natures, 64 | EndurantNatures, 65 | SubstantialNatures, 66 | MomentNatures, 67 | IntrinsicMomentNatures, 68 | ExtrinsicMomentNatures 69 | }; 70 | -------------------------------------------------------------------------------- /src/libs/ontouml/multilingual_text.ts: -------------------------------------------------------------------------------- 1 | import tags from 'language-tags'; 2 | 3 | export class MultilingualText { 4 | static defaultLanguage: string = 'en'; 5 | static languagePreference: string[] = ['en']; 6 | 7 | textMap: Map; 8 | 9 | constructor(value?: string, language?: string) { 10 | this.textMap = new Map(); 11 | if (value != null) this.addText(value, language); 12 | } 13 | 14 | getText(language?: string): string { 15 | if (language && tags.check(language)) { 16 | return this.textMap.get(language); 17 | } 18 | 19 | for (const lang of MultilingualText.languagePreference) { 20 | if (this.textMap.has(lang)) { 21 | return this.textMap.get(lang); 22 | } 23 | } 24 | 25 | return this.textMap.size > 0 ? [...this.textMap.entries()][0][1] : null; 26 | } 27 | 28 | addText(value: string, language?: string): void { 29 | language = language && tags.check(language) ? language : MultilingualText.defaultLanguage; 30 | this.textMap.set(language, value); 31 | } 32 | 33 | addAll(obj: object) { 34 | Object.entries(obj).forEach((entry) => { 35 | this.addText(entry[1], entry[0]); 36 | }); 37 | } 38 | 39 | entries(): [string, string][] { 40 | return [...this.textMap.entries()]; 41 | } 42 | 43 | clear(): void { 44 | this.textMap.clear(); 45 | } 46 | 47 | toJSON(): any { 48 | if (this.textMap.size == 0) return null; 49 | if (this.textMap.size == 1) return this.getText('en'); 50 | return this.textMap; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/libs/ontouml/ontouml_type.ts: -------------------------------------------------------------------------------- 1 | export enum OntoumlType { 2 | PROJECT_TYPE = 'Project', 3 | PACKAGE_TYPE = 'Package', 4 | CLASS_TYPE = 'Class', 5 | RELATION_TYPE = 'Relation', 6 | GENERALIZATION_TYPE = 'Generalization', 7 | GENERALIZATION_SET_TYPE = 'GeneralizationSet', 8 | PROPERTY_TYPE = 'Property', 9 | LITERAL_TYPE = 'Literal', 10 | DIAGRAM = 'Diagram', 11 | CLASS_VIEW = 'ClassView', 12 | RELATION_VIEW = 'RelationView', 13 | GENERALIZATION_VIEW = 'GeneralizationView', 14 | GENERALIZATION_SET_VIEW = 'GeneralizationSetView', 15 | PACKAGE_VIEW = 'PackageView', 16 | RECTANGLE = 'Rectangle', 17 | TEXT = 'Text', 18 | PATH = 'Path' 19 | } 20 | -------------------------------------------------------------------------------- /src/libs/ontouml/utils.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | 3 | function includesAll(superSet: T[], subSet: T[]): boolean { 4 | return !!superSet && !!subSet && _.isEmpty(_.difference(subSet, superSet)); 5 | } 6 | 7 | function intersects(setA: T[], setB: T[]): boolean { 8 | return !!setA && !!setB && !_.isEmpty(_.intersection(setA, setB)); 9 | } 10 | 11 | function equalContents(setA: Set, setB: Set): boolean; 12 | function equalContents(arrayA: T[], arrayB: T[]): boolean; 13 | function equalContents(a: T[] | Set, b: T[] | Set): boolean { 14 | if (!a || !b) { 15 | return false; 16 | } 17 | 18 | if (Array.isArray(a)) { 19 | a = new Set(a); 20 | } 21 | 22 | if (Array.isArray(b)) { 23 | b = new Set(b); 24 | } 25 | 26 | return a.size === b.size && [...a].every(content => (b as Set).has(content)); 27 | } 28 | 29 | function arrayFrom(input: T | T[] | Set): T[] { 30 | let resolvedInputArray: T[] = []; 31 | 32 | if (Array.isArray(input) && !_.isEmpty(input)) { 33 | resolvedInputArray = input; 34 | } else if (input instanceof Set) { 35 | resolvedInputArray = [...input]; 36 | } else if (input) { 37 | resolvedInputArray = [input as T]; 38 | } 39 | 40 | return resolvedInputArray; 41 | } 42 | 43 | export const utils = { 44 | includesAll, 45 | intersects, 46 | arrayFrom, 47 | equalContents 48 | }; 49 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/class_view.ts: -------------------------------------------------------------------------------- 1 | import { NodeView, Rectangle, Class, OntoumlElement, OntoumlType } from '..'; 2 | 3 | export class ClassView extends NodeView { 4 | constructor(base?: Partial) { 5 | super(OntoumlType.CLASS_VIEW, base); 6 | } 7 | 8 | createShape(): Rectangle { 9 | const rectangle = new Rectangle(); 10 | rectangle.width = 100; 11 | rectangle.height = 50; 12 | return rectangle; 13 | } 14 | 15 | getContents(): OntoumlElement[] { 16 | return super.getContents(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/connector_view.ts: -------------------------------------------------------------------------------- 1 | import { ModelElement, ElementView, Path } from '..'; 2 | import { OntoumlElement } from '../ontouml_element'; 3 | 4 | export abstract class ConnectorView extends ElementView { 5 | source: ElementView; 6 | target: ElementView; 7 | 8 | constructor(type: string, base?: Partial>) { 9 | super(type, base); 10 | 11 | this.source = base?.source || null; 12 | this.target = base?.target || null; 13 | } 14 | 15 | createShape(): Path { 16 | return new Path(); 17 | } 18 | 19 | toJSON(): any { 20 | const serialization = { 21 | source: null, 22 | target: null 23 | }; 24 | 25 | Object.assign(serialization, super.toJSON()); 26 | 27 | serialization.source = this.source?.getReference(); 28 | serialization.target = this.target?.getReference(); 29 | 30 | return serialization; 31 | } 32 | 33 | resolveReferences(elementReferenceMap: Map): void { 34 | super.resolveReferences(elementReferenceMap); 35 | 36 | const { source, target } = this; 37 | 38 | if (source) { 39 | this.source = OntoumlElement.resolveReference(source, elementReferenceMap, this, 'source'); 40 | } 41 | 42 | if (target) { 43 | this.target = OntoumlElement.resolveReference(target, elementReferenceMap, this, 'target'); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/diagram_element.ts: -------------------------------------------------------------------------------- 1 | import { OntoumlElement } from '..'; 2 | 3 | export abstract class DiagramElement extends OntoumlElement { 4 | constructor(type: string, base?: Partial) { 5 | super(type, base); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/element_view.ts: -------------------------------------------------------------------------------- 1 | import { ModelElement, OntoumlElement, DiagramElement, Shape } from '..'; 2 | 3 | export abstract class ElementView extends DiagramElement { 4 | modelElement: T; 5 | shape: S; 6 | 7 | constructor(type: string, base?: Partial>) { 8 | super(type, base); 9 | 10 | this.modelElement = base?.modelElement || null; 11 | this.shape = base?.shape || this.createShape(); 12 | 13 | this.shape.setContainer(this); 14 | } 15 | 16 | getContents(): OntoumlElement[] { 17 | return [this.shape]; 18 | } 19 | 20 | abstract createShape(): S; 21 | 22 | toJSON(): any { 23 | const serialization = { 24 | modelElement: null, 25 | shape: null 26 | }; 27 | 28 | Object.assign(serialization, super.toJSON()); 29 | 30 | serialization.modelElement = this.modelElement?.getReference(); 31 | 32 | return serialization; 33 | } 34 | 35 | resolveReferences(elementReferenceMap: Map): void { 36 | const { modelElement } = this; 37 | 38 | if (modelElement) { 39 | this.modelElement = OntoumlElement.resolveReference(modelElement, elementReferenceMap, this, 'modelElement'); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/generalization_set_view.ts: -------------------------------------------------------------------------------- 1 | import { GeneralizationSet, OntoumlType, ElementView, Text } from '..'; 2 | 3 | export class GeneralizationSetView extends ElementView { 4 | constructor(base?: Partial) { 5 | super(OntoumlType.GENERALIZATION_SET_VIEW, base); 6 | } 7 | 8 | createShape(): Text { 9 | const text = new Text(); 10 | text.width = 100; 11 | text.height = 50; 12 | return text; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/generalization_view.ts: -------------------------------------------------------------------------------- 1 | import { OntoumlType, ConnectorView, Path, Generalization } from '..'; 2 | 3 | export class GeneralizationView extends ConnectorView { 4 | constructor(base?: Partial) { 5 | super(OntoumlType.GENERALIZATION_VIEW, base); 6 | } 7 | 8 | createShape(): Path { 9 | return new Path(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/node_view.ts: -------------------------------------------------------------------------------- 1 | import { ModelElement, ElementView, RectangularShape } from '..'; 2 | 3 | export abstract class NodeView extends ElementView { 4 | constructor(type: string, base?: Partial>) { 5 | super(type, base); 6 | } 7 | 8 | getX(): number { 9 | return this.shape.getX(); 10 | } 11 | 12 | setX(x: number): void { 13 | this.shape.setX(x); 14 | } 15 | 16 | getY(): number { 17 | return this.shape.getY(); 18 | } 19 | 20 | setY(y: number): void { 21 | this.shape.setY(y); 22 | } 23 | 24 | getWidth(): number { 25 | return this.shape.width; 26 | } 27 | 28 | setWidth(width: number): void { 29 | this.shape.setWidth(width); 30 | } 31 | 32 | getHeight(): number { 33 | return this.shape.height; 34 | } 35 | 36 | setHeight(height: number): void { 37 | this.shape.setHeight(height); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/package_view.ts: -------------------------------------------------------------------------------- 1 | import { OntoumlElement, OntoumlType, NodeView, Rectangle, Package } from '..'; 2 | 3 | export class PackageView extends NodeView { 4 | constructor(base?: Partial) { 5 | super(OntoumlType.PACKAGE_VIEW, base); 6 | } 7 | 8 | createShape(): Rectangle { 9 | const rectangle = new Rectangle(); 10 | rectangle.width = 60; 11 | rectangle.height = 30; 12 | return rectangle; 13 | } 14 | 15 | getContents(): OntoumlElement[] { 16 | return super.getContents(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/path.ts: -------------------------------------------------------------------------------- 1 | import { OntoumlType, OntoumlElement, Shape, Point } from '..'; 2 | 3 | export class Path extends Shape { 4 | points: Point[]; 5 | 6 | constructor(base?: Partial) { 7 | super(OntoumlType.PATH, base); 8 | 9 | this.points = base?.points || null; 10 | } 11 | 12 | getContents(): OntoumlElement[] { 13 | return []; 14 | } 15 | 16 | moveTo(x: number, y: number): void { 17 | if (!this.points) { 18 | this.points = []; 19 | } 20 | 21 | this.points.push(new Point(x, y)); 22 | } 23 | 24 | setPoints(points: Point[]): void { 25 | this.points = []; 26 | if (points != null) this.addPoints(points); 27 | } 28 | 29 | addPoints(points: Point[]): void { 30 | if (points != null) points.forEach(p => this.addPoint(p)); 31 | } 32 | 33 | addPoint(point: Point): void { 34 | if (point != null) this.points.push(point); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/point.ts: -------------------------------------------------------------------------------- 1 | export class Point { 2 | x: number; 3 | y: number; 4 | 5 | constructor(x: number, y: number) { 6 | this.setX(x); 7 | this.setY(y); 8 | } 9 | 10 | getX(): number { 11 | return this.x; 12 | } 13 | 14 | setX(x: number): void { 15 | this.x = x ?? 0; 16 | } 17 | 18 | getY(): number { 19 | return this.y; 20 | } 21 | 22 | setY(y: number): void { 23 | this.y = y ?? 0; 24 | } 25 | 26 | toString(): string { 27 | return '(' + this.x + ', ' + this.y + ')'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/rectangle.ts: -------------------------------------------------------------------------------- 1 | import { OntoumlElement, OntoumlType, RectangularShape } from '..'; 2 | 3 | export class Rectangle extends RectangularShape { 4 | constructor(base?: Partial) { 5 | super(OntoumlType.RECTANGLE, base); 6 | } 7 | 8 | getContents(): OntoumlElement[] { 9 | return []; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/rectangular_shape.ts: -------------------------------------------------------------------------------- 1 | import { Shape, Point } from '..'; 2 | 3 | export abstract class RectangularShape extends Shape { 4 | topLeft: Point; 5 | width: number; 6 | height: number; 7 | 8 | constructor(type: string, base?: Partial) { 9 | super(type, base); 10 | 11 | this.topLeft = base?.topLeft || new Point(0, 0); 12 | this.width = base?.width || 20; 13 | this.height = base?.height || 10; 14 | } 15 | 16 | getX(): number { 17 | return this.topLeft.getX(); 18 | } 19 | 20 | setX(x: number): void { 21 | this.topLeft.setX(x); 22 | } 23 | 24 | getY(): number { 25 | return this.topLeft.getY(); 26 | } 27 | 28 | setY(y: number): void { 29 | this.topLeft.setY(y); 30 | } 31 | 32 | getWidth(): number { 33 | return this.width; 34 | } 35 | 36 | setWidth(width: number): void { 37 | this.width = width; 38 | } 39 | 40 | getHeight(): number { 41 | return this.height; 42 | } 43 | 44 | setHeight(height: number): void { 45 | this.height = height; 46 | } 47 | 48 | toJSON(): any { 49 | const serialization = { 50 | width: null, 51 | height: null, 52 | x: null, 53 | y: null 54 | }; 55 | 56 | Object.assign(serialization, super.toJSON()); 57 | 58 | delete serialization['topLeft']; 59 | 60 | serialization.x = this.topLeft?.x; 61 | serialization.y = this.topLeft?.y; 62 | 63 | return serialization; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/relation_view.ts: -------------------------------------------------------------------------------- 1 | import { OntoumlType, ConnectorView, Relation, OntoumlElement } from '..'; 2 | 3 | //TODO: This only works for binary relations. We still need to create a view for n-ary relations. 4 | export class RelationView extends ConnectorView { 5 | constructor(base?: Partial) { 6 | super(OntoumlType.RELATION_VIEW, base); 7 | } 8 | 9 | getContents(): OntoumlElement[] { 10 | return super.getContents(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/shape.ts: -------------------------------------------------------------------------------- 1 | import { DiagramElement } from '..'; 2 | import { OntoumlElement } from '../ontouml_element'; 3 | 4 | export abstract class Shape extends DiagramElement { 5 | constructor(type: string, base?: Partial) { 6 | super(type, base); 7 | } 8 | 9 | // No reference fields to resolve/replace 10 | resolveReferences(_elementReferenceMap: Map): void {} 11 | } 12 | -------------------------------------------------------------------------------- /src/libs/ontouml/view/text.ts: -------------------------------------------------------------------------------- 1 | import { OntoumlElement, OntoumlType, RectangularShape } from '..'; 2 | 3 | export class Text extends RectangularShape { 4 | value: string; 5 | 6 | constructor(base?: Partial) { 7 | super(OntoumlType.TEXT, base); 8 | 9 | this.value = base?.value || null; 10 | } 11 | 12 | getContents(): OntoumlElement[] { 13 | return []; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/Ontouml2DbOptions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { StrategyType } from '@libs/ontouml2db/constants/StrategyType'; 7 | import { DbmsSupported } from '@libs/ontouml2db/constants/DbmsSupported'; 8 | import { ServiceOptions } from '..'; 9 | 10 | export class Ontouml2DbOptions implements ServiceOptions { 11 | mappingStrategy: StrategyType; 12 | targetDBMS: DbmsSupported; 13 | isStandardizeNames: boolean; 14 | baseIri: String; 15 | generateSchema: boolean; 16 | generateConnection: boolean; 17 | hostName: string; 18 | databaseName: string; 19 | userConnection: string; 20 | passwordConnection: string; 21 | enumFieldToLookupTable: boolean; 22 | 23 | constructor(base: Partial = {}) { 24 | this.mappingStrategy = StrategyType.ONE_TABLE_PER_KIND; 25 | this.targetDBMS = DbmsSupported.GENERIC_SCHEMA; 26 | this.isStandardizeNames = true; 27 | this.baseIri = 'https://example.com'; 28 | this.generateSchema = true; 29 | this.generateConnection = false; 30 | this.enumFieldToLookupTable = true; 31 | 32 | Object.keys(base).forEach(key => (this[key] = base[key])); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/approaches/IStrategy.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface to the processing methods must implement. 3 | * 4 | * Author: Gustavo Ludovico Guidoni 5 | */ 6 | 7 | import { Graph } from '@libs/ontouml2db/graph/Graph'; 8 | import { Tracker } from '@libs/ontouml2db/tracker/Tracker'; 9 | 10 | export interface IStrategy { 11 | /** 12 | * Method responsible for performing the transformation of the graph. 13 | * 14 | * @param graph Graph to be modified. 15 | */ 16 | run(graph: Graph, tracker: Tracker): void; 17 | } 18 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/approaches/one_table_per_class/OneTablePerClass.ts: -------------------------------------------------------------------------------- 1 | import { IStrategy } from '@libs/ontouml2db/approaches/IStrategy'; 2 | import { Graph } from '@libs/ontouml2db/graph/Graph'; 3 | import { GraphGeneralization } from '@libs/ontouml2db/graph/GraphGeneralization'; 4 | import { GraphRelation } from '@libs/ontouml2db/graph/GraphRelation'; 5 | import { Increment } from '@libs/ontouml2db/util/Increment'; 6 | import { Cardinality } from '@libs/ontouml2db/constants/enumerations'; 7 | import { Tracker } from '@libs/ontouml2db/tracker/Tracker'; 8 | import { Util } from '@libs/ontouml2db/util/Util'; 9 | 10 | export class OneTablePerClass implements IStrategy { 11 | run(graph: Graph, tracker: Tracker): void { 12 | Util.transformGeneralizationToRelation1to1(graph); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/approaches/one_table_per_concrete_class/OneTablePerConcreteClass.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Transforms an OntoUML model into a model ready for final transformation and its 3 | * corresponding into a relational schema. 4 | * 5 | * The one table per concrete class approach is used: all non-sortals are flattened to kinds. 6 | * 7 | * Author: Gustavo L. Guidoni 8 | */ 9 | 10 | import { IStrategy } from '@libs/ontouml2db/approaches/IStrategy'; 11 | import { Graph } from '@libs/ontouml2db/graph/Graph'; 12 | import { Flatten } from '@libs/ontouml2db/approaches/processes/Flatten'; 13 | import { Tracker } from '@libs/ontouml2db/tracker/Tracker'; 14 | import { Util } from '@libs/ontouml2db/util/Util'; 15 | 16 | export class OneTablePerConcreteClass implements IStrategy { 17 | run(graph: Graph, tracker: Tracker): void { 18 | Flatten.doFlattening(graph, tracker); 19 | 20 | Util.transformGeneralizationToRelation1to1(graph); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/approaches/one_table_per_kind/OneTablePerKind.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Transforms an OntoUML model into a model ready for final transformation and its 3 | * corresponding into a relational schema. 4 | * 5 | * The one table per kind approach is used; all non-sortals are flattened to kinds, 6 | * and sortals lifted to kinds. 7 | * 8 | * Author: João Paulo A. Almeida; Gustavo L. Guidoni 9 | */ 10 | import { IStrategy } from '@libs/ontouml2db/approaches/IStrategy'; 11 | import { Graph } from '@libs/ontouml2db/graph/Graph'; 12 | import { Flatten } from '@libs/ontouml2db/approaches/processes/Flatten'; 13 | import { Lifting } from '@libs/ontouml2db/approaches/processes/Lifting'; 14 | import { Tracker } from '@libs/ontouml2db/tracker/Tracker'; 15 | 16 | export class OneTablePerKind implements IStrategy { 17 | run(graph: Graph, tracker: Tracker): void { 18 | Flatten.doFlattening(graph, tracker); 19 | 20 | Lifting.doLifting(graph, tracker); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/constants/DbmsSupported.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | export enum DbmsSupported { 6 | GENERIC_SCHEMA = 'Generic Schema', 7 | MYSQL = 'MySql', 8 | H2 = 'H2', 9 | SQLSERVER = 'SqlServer', 10 | ORACLE = 'Oracle', 11 | POSTGRE = 'Postgre' 12 | } 13 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/constants/StrategyType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Concentrates all the enumerations used by the graph to perform the transformation. 3 | * 4 | * Author: Gustavo L. Guidoni 5 | */ 6 | 7 | export enum StrategyType { 8 | ONE_TABLE_PER_CLASS = 'One Table per Class', 9 | ONE_TABLE_PER_KIND = 'One Table per Kind', 10 | ONE_TABLE_PER_CONCRETE_CLASS = 'One Table per Concrete Class' 11 | } 12 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/constants/enumerations.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Concentrates all the enumerations used by the graph to perform the transformation. 3 | * 4 | * Author: Gustavo L. Guidoni 5 | */ 6 | 7 | export enum AssociationType { 8 | RELATION_TYPE = 'Relation', 9 | GENERALIZATION_TYPE = 'Generalization', 10 | GENERALIZATION_SET_TYPE = 'GeneralizationSet' 11 | } 12 | 13 | export enum Cardinality { 14 | C1 = '1', 15 | C0_1 = '0..1', 16 | C1_N = '1..*', 17 | C0_N = '0..*', 18 | X = 'uninformed' 19 | } 20 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/convert/SolvesMultivaluedProperty.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { Increment } from '@libs/ontouml2db//util/Increment'; 7 | import { NodeProperty } from '@libs/ontouml2db/graph/NodeProperty'; 8 | import { GraphRelation } from '@libs/ontouml2db/graph/GraphRelation'; 9 | import { Node } from '@libs/ontouml2db/graph/Node'; 10 | import { Cardinality } from '@libs/ontouml2db/constants/enumerations'; 11 | import { Graph } from '@libs/ontouml2db/graph//Graph'; 12 | import { Tracker } from '@libs/ontouml2db/tracker/Tracker'; 13 | 14 | import { ClassStereotype } from '@libs/ontouml'; 15 | 16 | export class SolvesMultivaluedProperty { 17 | static solves(graph: Graph, tracker: Tracker): void { 18 | let idToRemove: string[] = []; 19 | 20 | for (let node of graph.getNodes()) { 21 | idToRemove.length = 0; 22 | for (let property of node.getProperties()) { 23 | if (property.isMultivalued()) { 24 | SolvesMultivaluedProperty.transformPropertyIntoNode(property, node, graph, tracker); 25 | idToRemove.push(property.getID()); 26 | } 27 | } 28 | 29 | while (idToRemove.length !== 0) { 30 | node.removeProperty(idToRemove.pop()); 31 | } 32 | } 33 | } 34 | 35 | static transformPropertyIntoNode(property: NodeProperty, node: Node, graph: Graph, tracker: Tracker): void { 36 | let newNode: Node; 37 | let relation: GraphRelation; 38 | 39 | newNode = new Node(Increment.getNext().toString(), property.getName(), ClassStereotype.MIXIN); 40 | 41 | newNode.addProperty(new NodeProperty(property.getID(), property.getName(), property.getDataType(), false, false)); 42 | 43 | relation = new GraphRelation( 44 | Increment.getNext().toString(), 45 | 'has' + property.getName() + '_' + Increment.getNext().toString(), 46 | node, 47 | Cardinality.C1, 48 | newNode, 49 | Cardinality.C0_N 50 | ); 51 | 52 | newNode.addRelation(relation); 53 | 54 | graph.addNode(newNode); 55 | graph.addRelation(relation); 56 | 57 | SolvesMultivaluedProperty.doTracking(node, newNode, property, graph, tracker); 58 | } 59 | 60 | static doTracking(tracedNode: Node, joinedNode: Node, property: NodeProperty, graph: Graph, tracker: Tracker): void { 61 | let sourceNodes: Node[] = graph.getSourceNodes(); 62 | 63 | sourceNodes.forEach(tracerNode => { 64 | if (tracerNode.existsProperty(property)) { 65 | if (property.isNullable()) { 66 | tracker.addJoinedNode(tracerNode, tracedNode, joinedNode, false); 67 | } else { 68 | tracker.addJoinedNode(tracerNode, tracedNode, joinedNode, true); 69 | } 70 | } 71 | }); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/convert/SolvesName.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { NodePropertyEnumeration } from '@libs/ontouml2db/graph/NodePropertyEnumeration'; 7 | import { Graph } from '@libs/ontouml2db/graph//Graph'; 8 | 9 | export class SolvesName { 10 | static solves(graph: Graph): void { 11 | for (let node of graph.getNodes()) { 12 | node.setName(SolvesName.adjust(node.getName())); 13 | for (let property of node.getProperties()) { 14 | property.setName(SolvesName.adjust(property.getName())); 15 | if (property instanceof NodePropertyEnumeration) { 16 | SolvesName.adjustEnumerationValues(property); 17 | } 18 | } 19 | } 20 | } 21 | 22 | static adjustEnumerationValues(enumeration: NodePropertyEnumeration): void { 23 | let values = enumeration.getValues(); 24 | 25 | for (let index = 0; index < values.length; index++) { 26 | values[index] = values[index].toUpperCase(); 27 | } 28 | } 29 | 30 | static adjust(name: string): string { 31 | let newName = ''; 32 | let index = 0; 33 | 34 | //In order not to add "_" in the properties which are written in uppercase. 35 | while (index < name.length && name.charAt(index) >= 'A' && name.charAt(index) <= 'Z') { 36 | newName += name.charAt(index); 37 | index++; 38 | } 39 | 40 | while (index < name.length) { 41 | if (name.charAt(index) >= 'A' && name.charAt(index) <= 'Z') { 42 | newName += '_'; 43 | } 44 | newName += name.charAt(index); 45 | index++; 46 | } 47 | return newName.toLowerCase(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/convert/SolvesPrimaryKey.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { Increment } from '@libs/ontouml2db/util/Increment'; 7 | import { NodeProperty } from '@libs/ontouml2db/graph/NodeProperty'; 8 | import { Graph } from '@libs/ontouml2db/graph/Graph'; 9 | 10 | export class SolvesPrimaryKey { 11 | static solves(graph: Graph): void { 12 | let pkName: string; 13 | let property: NodeProperty; 14 | let newID: string; 15 | 16 | for (let node of graph.getNodes()) { 17 | pkName = node.getName() + '_id'; 18 | newID = pkName + Increment.getNext().toString(); 19 | 20 | property = new NodeProperty(newID, pkName, 'int', false, false); 21 | 22 | property.setPrimaryKey(true); 23 | 24 | node.addPropertyAt(0, property); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/convert/ToEntityRelationship.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Transforms the Class model to the Entity-Relationship model. 3 | * 4 | * Author: Gustavo Ludovico Guidoni 5 | */ 6 | 7 | import { SolvesEnumeration } from '@libs/ontouml2db/convert/SolvesEnumeration'; 8 | import { SolvesPrimaryKey } from '@libs/ontouml2db/convert/SolvesPrimaryKey'; 9 | import { SolvesForeignKey } from '@libs/ontouml2db/convert/SolvesForeignKey'; 10 | import { SolvesName } from '@libs/ontouml2db/convert/SolvesName'; 11 | import { SolvesMultivaluedProperty } from '@libs/ontouml2db/convert/SolvesMultivaluedProperty'; 12 | import { SolvesCardinalityNtoN } from '@libs/ontouml2db/convert/SolvesCardinalityNtoN'; 13 | import { Graph } from '@libs/ontouml2db/graph//Graph'; 14 | import { Tracker } from '@libs/ontouml2db/tracker/Tracker'; 15 | 16 | export class ToEntityRelationship { 17 | static run(graph: Graph, tracker: Tracker, applyStandardizeNames: boolean, enumFiledToLookupTable: boolean): void { 18 | SolvesMultivaluedProperty.solves(graph, tracker); 19 | 20 | SolvesEnumeration.solves(graph, tracker, enumFiledToLookupTable); 21 | 22 | SolvesCardinalityNtoN.solves(graph, tracker); 23 | 24 | SolvesPrimaryKey.solves(graph); 25 | 26 | SolvesForeignKey.solves(graph); 27 | 28 | if (applyStandardizeNames) SolvesName.solves(graph); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/convert/ToRelationalSchema.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { Graph } from '@libs/ontouml2db/graph/Graph'; 7 | import { DbmsSupported } from '@libs/ontouml2db/constants/DbmsSupported'; 8 | import { DbmsInterface } from '@libs/ontouml2db/supported_database/DbmsInterface'; 9 | import { Generic } from '@libs/ontouml2db/supported_database/Generic'; 10 | import { H2 } from '@libs/ontouml2db/supported_database/H2'; 11 | import { MySql } from '../supported_database/MySql'; 12 | import { Oracle } from '../supported_database/Oracle'; 13 | import { Postgre } from '../supported_database/Postgre'; 14 | import { SqlServer } from '../supported_database/SqlServer'; 15 | 16 | export class ToRelationalSchema { 17 | static getSchema(graph: Graph, dbms: DbmsSupported): string { 18 | let targetDBMS: DbmsInterface; 19 | 20 | switch (dbms) { 21 | case DbmsSupported.H2: { 22 | targetDBMS = new H2(); 23 | break; 24 | } 25 | case DbmsSupported.MYSQL: { 26 | targetDBMS = new MySql(); 27 | break; 28 | } 29 | case DbmsSupported.ORACLE: { 30 | targetDBMS = new Oracle(); 31 | break; 32 | } 33 | case DbmsSupported.POSTGRE: { 34 | targetDBMS = new Postgre(); 35 | break; 36 | } 37 | case DbmsSupported.SQLSERVER: { 38 | targetDBMS = new SqlServer(); 39 | break; 40 | } 41 | 42 | default: 43 | targetDBMS = new Generic(); 44 | break; 45 | } 46 | 47 | return targetDBMS.getSchema(graph); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/graph/AssociationContainerInterface.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * An AssociationContainer is intended to group all the properties of a node. 3 | * A node is composed of a relationships set with other nodes. This interface contains the 4 | * necessary methods for handling node's associations. 5 | * 6 | * Author: Gustavo L. Guidoni 7 | */ 8 | 9 | import { GraphRelation } from '@libs/ontouml2db/graph/GraphRelation'; 10 | import { GraphGeneralization } from '@libs/ontouml2db/graph/GraphGeneralization'; 11 | import { GraphAssociation } from '@libs/ontouml2db/graph/GraphAssociation'; 12 | import { GraphGeneralizationSet } from '@libs/ontouml2db/graph/GraphGeneralizationSet'; 13 | 14 | export interface AssociationContainerInterface { 15 | /** 16 | * Adds a new association to the node. Each node has a list of its associations. In 17 | * this way, a association is referenced by the origin and destination node, forming 18 | * a bidirectional graph. 19 | * 20 | * @param relation Relatin to be added. 21 | */ 22 | addRelation(relation: GraphRelation): void; 23 | 24 | /** 25 | * Returns the associations with the node. 26 | * 27 | * @return An list with all the associations that arrive and depart from the 28 | * respective node. 29 | */ 30 | getRelations(): GraphRelation[]; 31 | 32 | /** 33 | * Returns the association that references the node. 34 | * 35 | * @param nodeID Node identifier to be searched. 36 | */ 37 | getAssociationWithNode(nodeID: string): GraphAssociation; 38 | 39 | /** 40 | * Adds a new generalization to the node's association set. 41 | * 42 | * @param generalization Generalization to be added 43 | */ 44 | addGeneralization(generalization: GraphGeneralization); 45 | 46 | /** 47 | * Returns generalizations belonging to the node. 48 | */ 49 | getGeneralizations(): GraphGeneralization[]; 50 | 51 | /** 52 | * Returns generalization sets belonging to the node, when the node is a 53 | * generalization of some node. 54 | */ 55 | getGeneralizationSets(): GraphGeneralizationSet[]; 56 | 57 | /** 58 | * Removes the association form the node. The association still exists in the graph. 59 | * @param association 60 | */ 61 | deleteAssociation(association: GraphAssociation): void; 62 | 63 | /** 64 | * Checks whether the current node is a specialist node of some generalization. 65 | * 66 | * @return True if the node is a specialization of another node, otherwise false. 67 | */ 68 | isSpecialization(): boolean; 69 | 70 | /** 71 | * Checks whether the current node has any specialization. 72 | * 73 | * @return True if the node has at last one specialization node, otherwise false. 74 | */ 75 | hasSpecialization(): boolean; 76 | 77 | /** 78 | * Returns all associations formatted as a string. 79 | */ 80 | toString(): string; 81 | } 82 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/graph/NodePropertyEnumeration.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The Enumeration is treated as a special type of Property. In addition to 3 | * having all the features of OntoProperty, it is also capable of adding 4 | * several values of the same type. 5 | * 6 | * Author: Gustavo Ludovico Guidoni 7 | */ 8 | 9 | import { NodeProperty } from '@libs/ontouml2db/graph/NodeProperty'; 10 | 11 | export class NodePropertyEnumeration extends NodeProperty { 12 | private values: string[]; 13 | 14 | constructor(id: string, name: string, dataType: string, isNull: boolean, multiValues: boolean) { 15 | super(id, name, dataType, isNull, multiValues); 16 | this.values = []; 17 | } 18 | 19 | /** 20 | * Adds a new value belonging to the Enumeration. 21 | * 22 | * @param value. Name to be added. 23 | */ 24 | addValue(value: string): void { 25 | this.values.push(value); 26 | } 27 | 28 | /** 29 | * Returns the names belonging to the Enumeration. 30 | * 31 | * @return The ArrayList with the names. 32 | */ 33 | getValues(): string[] { 34 | return this.values; 35 | } 36 | 37 | /** 38 | * Returns the enumerations as string. 39 | */ 40 | toString(): string { 41 | let result = this.getName() + ': ' + this.getDataType() + ' ['; 42 | 43 | for (let str of this.values) { 44 | result += str + ' | '; 45 | } 46 | result += ']'; 47 | 48 | return result; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | export * from './Ontouml2Db'; 6 | export * from './Ontouml2DbOptions'; 7 | export * from './constants/StrategyType'; 8 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/obda/GenerateConnection.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { Ontouml2DbOptions } from '@libs/ontouml2db/Ontouml2DbOptions'; 7 | import { H2 } from '@libs/ontouml2db/supported_database/H2'; 8 | import { DbmsInterface } from '@libs/ontouml2db/supported_database/DbmsInterface'; 9 | import { MySql } from '@libs/ontouml2db/supported_database/MySql'; 10 | import { Oracle } from '@libs/ontouml2db/supported_database/Oracle'; 11 | import { Postgre } from '@libs/ontouml2db/supported_database/Postgre'; 12 | import { SqlServer } from '@libs/ontouml2db/supported_database/SqlServer'; 13 | import { DbmsSupported } from '@libs/ontouml2db/constants/DbmsSupported'; 14 | import { Generic } from '../supported_database/Generic'; 15 | 16 | export class GenerateConnection { 17 | static getFile(options: Ontouml2DbOptions): string { 18 | let database: DbmsInterface; 19 | 20 | database = this.getDatabase(options.targetDBMS); 21 | 22 | return database.getConnectionToProtege(options); 23 | } 24 | 25 | static getDatabase(db: DbmsSupported): DbmsInterface { 26 | switch (db) { 27 | case DbmsSupported.GENERIC_SCHEMA: { 28 | return new Generic(); 29 | } 30 | case DbmsSupported.H2: { 31 | return new H2(); 32 | } 33 | case DbmsSupported.MYSQL: { 34 | return new MySql(); 35 | } 36 | case DbmsSupported.ORACLE: { 37 | return new Oracle(); 38 | } 39 | case DbmsSupported.POSTGRE: { 40 | return new Postgre(); 41 | } 42 | case DbmsSupported.SQLSERVER: { 43 | return new SqlServer(); 44 | } 45 | default: 46 | throw new Error('There is no support for the chosen database.'); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/obda/GenerateObda.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { Ontouml2DbOptions } from '@libs/ontouml2db/Ontouml2DbOptions'; 7 | import { GenerateObdaMappingId } from '@libs/ontouml2db/obda/GenerateObdaMappingId'; 8 | import { GenerateObdaTarget } from '@libs/ontouml2db/obda/GenerateObdaTarget'; 9 | import { GenerateObdaSource } from '@libs/ontouml2db/obda/GenerateObdaSource'; 10 | import { Tracker } from '@libs/ontouml2db/tracker/Tracker'; 11 | import { TracedNode } from '../tracker/TracedNode'; 12 | 13 | export class GenerateObda { 14 | static getFile(options: Ontouml2DbOptions, tracker: Tracker): string { 15 | let file: string; 16 | file = this.generatePrefixDeclaration(options); 17 | 18 | file += this.generateMappingDeclaration(options, tracker); 19 | 20 | return file; 21 | } 22 | 23 | static generatePrefixDeclaration(options: Ontouml2DbOptions): string { 24 | return ( 25 | '[PrefixDeclaration]\n' + 26 | ': ' + 27 | options.baseIri + 28 | '#\n' + 29 | 'gufo: http://purl.org/nemo/gufo#\n' + 30 | 'rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns#\n' + 31 | 'rdfs: http://www.w3.org/2000/01/rdf-schema#\n' + 32 | 'owl: http://www.w3.org/2002/07/owl#\n' + 33 | 'xsd: http://www.w3.org/2001/XMLSchema#\n' + 34 | '\n' 35 | ); 36 | } 37 | 38 | static generateMappingDeclaration(options: Ontouml2DbOptions, tracker: Tracker): string { 39 | let projectName: string = options.databaseName; 40 | let first: boolean; 41 | let text: string = '[MappingDeclaration] @collection [[\n\n'; 42 | 43 | for (let trace of tracker.getTraceMap().values()) { 44 | first = true; 45 | trace.getTargetNodes().forEach((tracedNode: TracedNode) => { 46 | text += GenerateObdaMappingId.generate(trace.getSourceNode(), projectName, first); 47 | 48 | text += GenerateObdaTarget.generate(trace.getSourceNode(), projectName, tracedNode); 49 | 50 | text += GenerateObdaSource.generate(trace, tracedNode); 51 | 52 | first = false; 53 | 54 | text += '\n'; 55 | }); 56 | } 57 | text += ']]\n'; 58 | 59 | return text; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/obda/GenerateObdaMappingId.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { Increment } from '@libs/ontouml2db/util/Increment'; 7 | import { Node } from '@libs/ontouml2db/graph/Node'; 8 | 9 | export class GenerateObdaMappingId { 10 | static generate(sourceNode: Node, project: string, first: boolean): string { 11 | let text: string = ''; 12 | 13 | text += 'mappingId '; 14 | text += project; 15 | text += '-'; 16 | if (sourceNode.getAssociationNameNtoN() == null) { 17 | //when the class is generated from an N:N relationship 18 | text += sourceNode.getName(); 19 | } else { 20 | text += sourceNode.getAssociationNameNtoN(); 21 | } 22 | if (!first) { 23 | //when a class is mapped to multiple classes. 24 | text += Increment.getNext(); 25 | } 26 | text += '\n'; 27 | 28 | return text; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/supported_database/DbmsInterface.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { Graph } from '@libs/ontouml2db/graph/Graph'; 7 | import { Ontouml2DbOptions } from '@libs/ontouml2db/Ontouml2DbOptions'; 8 | 9 | export interface DbmsInterface { 10 | /** 11 | * Returns the relational schema script for the graph (ER). 12 | * 13 | * @param target Graph (ER) to be generated the script with the relational scheme. 14 | */ 15 | getSchema(graph: Graph): string; 16 | 17 | /** 18 | * Returns the connection from the database to Protege. 19 | */ 20 | getConnectionToProtege(options: Ontouml2DbOptions): string; 21 | } 22 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/supported_database/H2.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { DbmsInterface } from '@libs/ontouml2db/supported_database/DbmsInterface'; 7 | import { Graph } from '@libs/ontouml2db/graph/Graph'; 8 | import { NodeProperty } from '@libs/ontouml2db/graph/NodeProperty'; 9 | import { Generic } from '@libs/ontouml2db/supported_database/Generic'; 10 | import { Ontouml2DbOptions } from '@libs/ontouml2db/Ontouml2DbOptions'; 11 | 12 | export class H2 extends Generic implements DbmsInterface { 13 | constructor() { 14 | super(); 15 | this.types.set('boolean', 'BOOLEAN'); 16 | this.types.set('byte', 'BINARY(8)'); 17 | } 18 | 19 | getSchema(graph: Graph): string { 20 | let ddl: string = ''; 21 | 22 | ddl = this.createTables(graph); 23 | 24 | ddl += this.createForeignKeys(graph); 25 | 26 | return ddl; 27 | } 28 | 29 | createTableDescription() { 30 | return 'CREATE TABLE IF NOT EXISTS '; 31 | } 32 | 33 | getPKDescription(property: NodeProperty): string { 34 | if (property.isPrimaryKey()) { 35 | if (property.isPrimaryKeyAutoIncrement()) return ' IDENTITY PRIMARY KEY'; 36 | return ' PRIMARY KEY'; 37 | } 38 | return ''; 39 | } 40 | 41 | //***************************************************************************************** 42 | getConnectionToProtege(options: Ontouml2DbOptions): string { 43 | let stringConnection: string = ''; 44 | 45 | let today = new Date(); 46 | 47 | stringConnection += '#Ontouml2DB ' + today.toDateString() + '\n'; 48 | stringConnection += 'jdbc.url=jdbc:h2:tcp:' + '//' + options.hostName + '/' + options.databaseName + '\n'; 49 | stringConnection += 'jdbc.driver=org.h2.Driver' + '\n'; 50 | stringConnection += 'jdbc.user=' + options.userConnection + '\n'; 51 | stringConnection += 'jdbc.name=ontouml2-db00-ufes-nemo-000000000001' + '\n'; 52 | stringConnection += 'jdbc.password=' + options.passwordConnection + '\n'; 53 | 54 | return stringConnection; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/supported_database/MySql.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { DbmsInterface } from '@libs/ontouml2db/supported_database/DbmsInterface'; 7 | import { Generic } from '@libs/ontouml2db/supported_database/Generic'; 8 | import { NodeProperty } from '@libs/ontouml2db/graph/NodeProperty'; 9 | import { Ontouml2DbOptions } from '@libs/ontouml2db/Ontouml2DbOptions'; 10 | 11 | export class MySql extends Generic implements DbmsInterface { 12 | constructor() { 13 | super(); 14 | this.types.set('boolean', 'TINYINT(1)'); 15 | this.types.set('byte', 'BINARY(8)'); 16 | } 17 | 18 | createTableDescription() { 19 | return 'CREATE TABLE IF NOT EXISTS '; 20 | } 21 | 22 | getPKDescription(property: NodeProperty): string { 23 | if (property.isPrimaryKey()) { 24 | if (property.isPrimaryKeyAutoIncrement()) return ' AUTO_INCREMENT PRIMARY KEY'; 25 | return ' PRIMARY KEY'; 26 | } 27 | return ''; 28 | } 29 | 30 | getConnectionToProtege(options: Ontouml2DbOptions): string { 31 | let stringConnection: string = ''; 32 | 33 | let today = new Date(); 34 | 35 | stringConnection += '#Ontouml2DB ' + today.toDateString() + '\n'; 36 | stringConnection += 'jdbc.url=jdbc:mysql:tcp:' + '//' + options.hostName + '/' + options.databaseName + '\n'; 37 | stringConnection += 'jdbc.driver=org.mysql.Driver' + '\n'; 38 | stringConnection += 'jdbc.user=' + options.userConnection + '\n'; 39 | stringConnection += 'jdbc.name=ontouml2-db00-ufes-nemo-000000000001' + '\n'; 40 | stringConnection += 'jdbc.password=' + options.passwordConnection + '\n'; 41 | 42 | return stringConnection; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/supported_database/Oracle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { DbmsInterface } from '@libs/ontouml2db/supported_database/DbmsInterface'; 7 | import { Node } from '@libs/ontouml2db/graph/Node'; 8 | import { NodeProperty } from '@libs/ontouml2db/graph/NodeProperty'; 9 | import { Ontouml2DbOptions } from '@libs/ontouml2db/Ontouml2DbOptions'; 10 | import { Generic } from '@libs/ontouml2db/supported_database/Generic'; 11 | import { Util } from '@libs/ontouml2db/util/Util'; 12 | 13 | export class Oracle extends Generic implements DbmsInterface { 14 | constructor() { 15 | super(); 16 | this.types.set('boolean', 'CHAR(1)'); 17 | this.types.set('byte', 'RAW(1)'); 18 | this.types.set('char', 'CHAR(3)'); 19 | this.types.set('double', 'NUMBER(20,4)'); 20 | this.types.set('float', 'NUMBER(10,2)'); 21 | this.types.set('int', 'NUMBER(10,0)'); 22 | this.types.set('long', 'NUMBER(20,0)'); 23 | this.types.set('short', 'NUMBER(3,0)'); 24 | this.types.set('string', 'VARCHAR2(20)'); 25 | } 26 | 27 | createTableDescription() { 28 | return 'CREATE TABLE '; 29 | } 30 | 31 | getPKDescription(property: NodeProperty): string { 32 | if (property.isPrimaryKey() && property.isPrimaryKeyAutoIncrement()) { 33 | return ' GENERATED ALWAYS AS IDENTITY '; 34 | } 35 | return ''; 36 | } 37 | 38 | getConstraintTable(node: Node): string { 39 | return ( 40 | '\n,' + 41 | Util.getSpaces(',', 8) + 42 | 'CONSTRAINT pk_' + 43 | node.getName() + 44 | ' PRIMARY KEY( ' + 45 | node.getPrimaryKey().getName() + 46 | ' )' 47 | ); 48 | } 49 | 50 | getConnectionToProtege(options: Ontouml2DbOptions): string { 51 | let stringConnection: string = ''; 52 | 53 | let today = new Date(); 54 | 55 | stringConnection += '#Ontouml2DB ' + today.toDateString() + '\n'; 56 | stringConnection += 'jdbc.url=jdbc:oracle:tcp:' + '//' + options.hostName + '/' + options.databaseName + '\n'; 57 | stringConnection += 'jdbc.driver=org.oracle.Driver' + '\n'; 58 | stringConnection += 'jdbc.user=' + options.userConnection + '\n'; 59 | stringConnection += 'jdbc.name=ontouml2-db00-ufes-nemo-000000000001' + '\n'; 60 | stringConnection += 'jdbc.password=' + options.passwordConnection + '\n'; 61 | 62 | return stringConnection; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/supported_database/SqlServer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo Ludovico Guidoni 4 | */ 5 | 6 | import { DbmsInterface } from '@libs/ontouml2db/supported_database/DbmsInterface'; 7 | import { Generic } from '@libs/ontouml2db/supported_database/Generic'; 8 | import { NodeProperty } from '@libs/ontouml2db/graph/NodeProperty'; 9 | import { Ontouml2DbOptions } from '@libs/ontouml2db/Ontouml2DbOptions'; 10 | 11 | export class SqlServer extends Generic implements DbmsInterface { 12 | constructor() { 13 | super(); 14 | this.types.set('boolean', 'BIT'); 15 | this.types.set('byte', 'BINARY(8)'); 16 | this.types.set('double', 'REAL'); 17 | this.types.set('float', 'FLOAT(53)'); 18 | } 19 | 20 | createTableDescription() { 21 | return 'CREATE TABLE '; 22 | } 23 | 24 | getPKDescription(property: NodeProperty): string { 25 | if (property.isPrimaryKey()) { 26 | if (property.isPrimaryKeyAutoIncrement()) return ' IDENTITY(1,1) PRIMARY KEY'; 27 | return ' PRIMARY KEY'; 28 | } 29 | return ''; 30 | } 31 | 32 | getConnectionToProtege(options: Ontouml2DbOptions): string { 33 | let stringConnection: string = ''; 34 | 35 | let today = new Date(); 36 | 37 | stringConnection += '#Ontouml2DB ' + today.toDateString() + '\n'; 38 | stringConnection += 'jdbc.url=jdbc:sqlserver:tcp:' + '//' + options.hostName + '/' + options.databaseName + '\n'; 39 | stringConnection += 'jdbc.driver=org.sqlserver.Driver' + '\n'; 40 | stringConnection += 'jdbc.user=' + options.userConnection + '\n'; 41 | stringConnection += 'jdbc.name=ontouml2-db00-ufes-nemo-000000000001' + '\n'; 42 | stringConnection += 'jdbc.password=' + options.passwordConnection + '\n'; 43 | 44 | return stringConnection; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/util/Increment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo L. Guidoni 4 | */ 5 | 6 | export class Increment { 7 | private static next: number; 8 | 9 | static getNext(): number { 10 | if (Increment.next == null) this.next = 1; 11 | return Increment.next++; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/libs/ontouml2db/util/Util.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Gustavo L. Guidoni 4 | */ 5 | 6 | import { Node } from '@libs/ontouml2db/graph/Node'; 7 | 8 | import { ClassStereotype } from '@libs/ontouml'; 9 | import { Graph } from '../graph/Graph'; 10 | import { GraphGeneralization } from '../graph/GraphGeneralization'; 11 | import { GraphRelation } from '../graph/GraphRelation'; 12 | import { Increment } from './Increment'; 13 | import { Cardinality } from '@libs/ontouml2db/constants/enumerations'; 14 | 15 | export class Util { 16 | static findNodeById(id: string, nodes: Node[]): Node { 17 | let i: number = 0; 18 | 19 | while (i < nodes.length) { 20 | if (nodes[i].getId() === id) return nodes[i]; 21 | i++; 22 | } 23 | return null; 24 | } 25 | 26 | static isNonSortal(type: ClassStereotype): boolean { 27 | if ( 28 | type === ClassStereotype.CATEGORY || 29 | type === ClassStereotype.ROLE_MIXIN || 30 | type === ClassStereotype.PHASE_MIXIN || 31 | type === ClassStereotype.MIXIN 32 | ) 33 | return true; 34 | else return false; 35 | } 36 | 37 | static isSortalNonKind(type: ClassStereotype): boolean { 38 | if (type === ClassStereotype.ROLE || type === ClassStereotype.PHASE || type === ClassStereotype.SUBKIND) return true; 39 | else return false; 40 | } 41 | 42 | static getSpaces(name: string, qtd: number): string { 43 | let tam: number = name.length; 44 | let spaces: string; 45 | 46 | spaces = ' '; 47 | tam++; 48 | 49 | while (tam <= qtd) { 50 | spaces += ' '; 51 | tam++; 52 | } 53 | return spaces; 54 | } 55 | 56 | static transformGeneralizationToRelation1to1(graph: Graph): void { 57 | let generalization: GraphGeneralization; 58 | let newRelation: GraphRelation; 59 | let id: string; 60 | let toDestroy: GraphGeneralization[] = []; 61 | 62 | for (let association of graph.getAssociations()) { 63 | if (association instanceof GraphGeneralization) { 64 | generalization = association; 65 | 66 | id = Increment.getNext().toString(); 67 | 68 | newRelation = new GraphRelation( 69 | id, //ID 70 | id, //association name 71 | generalization.getGeneral(), //sourceNode 72 | Cardinality.C1, //sourceCardinality 73 | generalization.getSpecific(), //targetNode 74 | Cardinality.C1 //targetCardinality 75 | ); 76 | 77 | generalization.getGeneral().addRelation(newRelation); 78 | generalization.getSpecific().addRelation(newRelation); 79 | graph.addRelation(newRelation); 80 | 81 | toDestroy.push(generalization); 82 | } 83 | } 84 | 85 | for (generalization of toDestroy) { 86 | graph.removeAssociation(generalization); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/libs/ontouml2gufo/annotation_function.ts: -------------------------------------------------------------------------------- 1 | import { ModelElement, Relation } from '@libs/ontouml'; 2 | import { Ontouml2Gufo } from './'; 3 | import tags from 'language-tags'; 4 | 5 | export function transformAnnotations(transformer: Ontouml2Gufo, element: ModelElement): boolean { 6 | const labels = transformer.options.getCustomLabels(element) || {}; 7 | const uri = transformer.getUri(element); 8 | 9 | for (const language of Object.keys(labels)) { 10 | if (tags.check(language)) { 11 | transformer.addLiteralQuad(uri, 'rdfs:label', labels[language], language); 12 | } 13 | } 14 | 15 | const { propertyAssignments } = element; 16 | 17 | if (propertyAssignments) { 18 | for (const language of Object.keys(propertyAssignments)) { 19 | if (tags.check(language)) { 20 | transformer.addLiteralQuad(uri, 'rdfs:label', propertyAssignments[language], language); 21 | } 22 | } 23 | } 24 | 25 | if (labels.default) { 26 | transformer.addLiteralQuad(uri, 'rdfs:label', labels.default); 27 | } 28 | 29 | if (element.name) { 30 | for (const [language, value] of element.name.entries()) { 31 | if (tags.check(language)) { 32 | transformer.addLiteralQuad(uri, 'rdfs:label', value, language); 33 | } 34 | } 35 | } 36 | 37 | if (element.description) { 38 | for (const [language, value] of element.description.entries()) { 39 | if (tags.check(language)) { 40 | transformer.addLiteralQuad(uri, 'rdfs:comment', value, language); 41 | } 42 | } 43 | } 44 | 45 | return true; 46 | } 47 | 48 | export function transformInverseAnnotations(transformer: Ontouml2Gufo, relation: Relation) { 49 | transformAnnotations(transformer, relation.properties[0]); 50 | } 51 | -------------------------------------------------------------------------------- /src/libs/ontouml2gufo/attribute_functions.ts: -------------------------------------------------------------------------------- 1 | import { OntoumlType, Property, Class } from '@libs/ontouml'; 2 | import { Ontouml2Gufo, transformAnnotations } from './'; 3 | 4 | export function transformAttribute(transformer: Ontouml2Gufo, attribute: Property): boolean { 5 | const container = attribute.container; 6 | 7 | if (container.type !== OntoumlType.CLASS_TYPE) { 8 | return false; 9 | } 10 | 11 | const containerClass: Class = container as Class; 12 | 13 | const attributeUri = transformer.getUri(attribute); 14 | const containerUri = transformer.getUri(containerClass); 15 | 16 | const containerIsDatatype = containerClass.hasDatatypeStereotype(); 17 | const containerIsConcreteIndividual = !containerClass.isRestrictedToAbstract(); 18 | 19 | const isTypelessAttribute = !attribute.propertyType; 20 | const isPrimitiveAttribute = attribute.propertyType && (attribute.propertyType as Class).isPrimitiveDatatype(); 21 | 22 | transformer.addQuad(attributeUri, 'rdfs:domain', containerUri); 23 | 24 | if (!isTypelessAttribute) { 25 | const attributeTypeUri = transformer.getUri(attribute.propertyType); 26 | transformer.addQuad(attributeUri, 'rdfs:range', attributeTypeUri); 27 | } 28 | 29 | if (isTypelessAttribute || isPrimitiveAttribute) { 30 | transformer.addQuad(attributeUri, 'rdf:type', 'owl:DatatypeProperty'); 31 | 32 | if (containerIsDatatype) { 33 | transformer.addQuad(attributeUri, 'rdfs:subPropertyOf', 'gufo:hasValueComponent'); 34 | } else if (containerIsConcreteIndividual) { 35 | transformer.addQuad(attributeUri, 'rdfs:subPropertyOf', 'gufo:hasQualityValue'); 36 | } 37 | } else { 38 | transformer.addQuad(attributeUri, 'rdf:type', 'owl:ObjectProperty'); 39 | 40 | const isComplexAttribute = (attribute.propertyType as Class).isComplexDatatype(); 41 | const isEnumeratedAttribute = (attribute.propertyType as Class).hasEnumerationStereotype(); 42 | 43 | if (containerIsConcreteIndividual && (isComplexAttribute || isEnumeratedAttribute)) { 44 | transformer.addQuad(attributeUri, 'rdfs:subPropertyOf', 'gufo:hasReifiedQualityValue'); 45 | } 46 | } 47 | 48 | transformAnnotations(transformer, attribute); 49 | 50 | return true; 51 | } 52 | -------------------------------------------------------------------------------- /src/libs/ontouml2gufo/generalization_functions.ts: -------------------------------------------------------------------------------- 1 | import { Generalization } from '@libs/ontouml'; 2 | import { Ontouml2Gufo } from './'; 3 | 4 | export function transformGeneralization(transformer: Ontouml2Gufo, generalization: Generalization) { 5 | const specific = generalization.specific; 6 | const general = generalization.general; 7 | 8 | const specificUri = transformer.getUri(specific); 9 | const generalUri = transformer.getUri(general); 10 | 11 | if (generalization.involvesClasses()) { 12 | transformer.addQuad(specificUri, 'rdfs:subClassOf', generalUri); 13 | } 14 | 15 | if (generalization.involvesRelations()) { 16 | transformer.addQuad(specificUri, 'rdfs:subPropertyOf', generalUri); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/libs/ontouml2gufo/generalization_set_functions.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { Generalization, GeneralizationSet, OntoumlType, Class } from '@libs/ontouml'; 3 | import { Ontouml2Gufo } from './'; 4 | 5 | const N3 = require('n3'); 6 | const { namedNode } = N3.DataFactory; 7 | 8 | export const transformGeneralizationSet = (transformer: Ontouml2Gufo, genSet: GeneralizationSet) => { 9 | if (!genSet.generalizations || genSet.generalizations.length === 0 || (!genSet.isComplete && !genSet.isDisjoint)) return; 10 | 11 | const classChildren = (genSet.generalizations as Generalization[]) 12 | .map(gen => gen.specific) 13 | .filter(child => child.type === OntoumlType.CLASS_TYPE); 14 | const onlyClassChildren = classChildren.length === genSet.generalizations.length; 15 | 16 | if (!onlyClassChildren) return; 17 | 18 | const classParents = genSet.generalizations.map((gen: Generalization) => gen.getGeneralClass()); 19 | const onlyClassParent = classParents.length === genSet.generalizations.length; 20 | const parent = genSet.getGeneralClass(); 21 | const uniqueParent = !!parent; 22 | 23 | if (!uniqueParent || !onlyClassParent) { 24 | return; 25 | } 26 | 27 | if (genSet.isDisjoint) { 28 | const rigidOrAbstractChildren = genSet 29 | .getSpecificClasses() 30 | .filter((child: Class) => child.hasRigidStereotype() || (child.isRestrictedToAbstract() && !child.isPrimitiveDatatype())); 31 | 32 | if (rigidOrAbstractChildren.length > 1) { 33 | const childrenNodes = rigidOrAbstractChildren.map(_class => namedNode(transformer.getUri(_class))); 34 | transformer.addQuad( 35 | transformer.writer.blank(namedNode('rdf:type'), namedNode('owl:AllDisjointClasses')), 36 | namedNode('owl:members'), 37 | transformer.writer.list(childrenNodes) 38 | ); 39 | } 40 | } 41 | 42 | if (genSet.isComplete && classChildren.length > 1) { 43 | const parentUri = transformer.getUri(parent); 44 | const childrenNodes = classChildren.map(_class => namedNode(transformer.getUri(_class))); 45 | 46 | transformer.addQuad( 47 | namedNode(parentUri), 48 | namedNode('owl:equivalentClass'), 49 | transformer.writer.blank([ 50 | { 51 | predicate: namedNode('rdf:type'), 52 | object: namedNode('owl:Class') 53 | }, 54 | { 55 | predicate: namedNode('owl:unionOf'), 56 | object: transformer.writer.list(childrenNodes) 57 | } 58 | ]) 59 | ); 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /src/libs/ontouml2gufo/index.ts: -------------------------------------------------------------------------------- 1 | export * from './annotation_function'; 2 | export * from './attribute_functions'; 3 | export * from './cardinality_functions'; 4 | export * from './class_functions'; 5 | export * from './generalization_functions'; 6 | export * from './generalization_set_functions'; 7 | export * from './inspector'; 8 | export * from './issue'; 9 | export * from './ontouml2gufo'; 10 | export * from './options'; 11 | export * from './prefix_functions'; 12 | export * from './relation_functions'; 13 | export * from './relations_inverse_functions'; 14 | export * from './uri_manager'; 15 | -------------------------------------------------------------------------------- /src/libs/ontouml2gufo/options.ts: -------------------------------------------------------------------------------- 1 | import { ModelElement, Package } from '@libs/ontouml'; 2 | import { ServiceOptions } from '@libs/service_options'; 3 | 4 | export class Ontouml2GufoOptions implements ServiceOptions { 5 | format: string; 6 | baseIri: string; 7 | basePrefix: string; 8 | uriFormatBy: string; 9 | createObjectProperty: boolean; 10 | createInverses: boolean; 11 | prefixPackages: boolean; 12 | customElementMapping?: { 13 | [key: string]: { 14 | label?: { 15 | [key: string]: string; 16 | }; 17 | uri?: string; 18 | }; 19 | }; 20 | customPackageMapping?: { 21 | [key: string]: { 22 | prefix?: string; 23 | uri?: string; 24 | }; 25 | }; 26 | 27 | constructor(base: Partial = {}) { 28 | this.format = 'Turtle'; 29 | this.baseIri = 'https://example.com'; 30 | this.uriFormatBy = 'name'; 31 | this.createObjectProperty = true; 32 | this.createInverses = false; 33 | this.prefixPackages = false; 34 | this.customElementMapping = {}; 35 | this.customPackageMapping = {}; 36 | 37 | Object.keys(base).forEach(key => (this[key] = base[key])); 38 | } 39 | 40 | getCustomUri(element: ModelElement): string { 41 | const allMappings = this.customElementMapping; 42 | 43 | let elementCustomMapping = allMappings[element.id]; 44 | 45 | if (elementCustomMapping && elementCustomMapping.uri) { 46 | return elementCustomMapping.uri; 47 | } 48 | 49 | elementCustomMapping = allMappings[element.getName()]; 50 | 51 | if (elementCustomMapping && elementCustomMapping.uri) { 52 | return elementCustomMapping.uri; 53 | } 54 | 55 | return null; 56 | } 57 | 58 | getCustomLabels(element: ModelElement) { 59 | const allMappings = this.customElementMapping; 60 | 61 | let elementCustomMapping = allMappings[element.id]; 62 | 63 | if (elementCustomMapping && elementCustomMapping.label) { 64 | return elementCustomMapping.label; 65 | } 66 | 67 | elementCustomMapping = allMappings[element.getName()]; 68 | 69 | if (elementCustomMapping && elementCustomMapping.label) { 70 | return elementCustomMapping.label; 71 | } 72 | 73 | return null; 74 | } 75 | 76 | // type CustomPrefixData = { customPrefix?: string; customUri: string }; 77 | 78 | getCustomPackagePrefix(pkg: Package): string { 79 | const idMapping = this.customPackageMapping[pkg.id]; 80 | 81 | if (idMapping && idMapping.prefix) { 82 | return idMapping.prefix; 83 | } 84 | 85 | const packageName = pkg.getName(); 86 | const nameMapping = this.customPackageMapping[packageName]; 87 | if (nameMapping && nameMapping.prefix) { 88 | return nameMapping.prefix; 89 | } 90 | 91 | return null; 92 | } 93 | 94 | getCustomPackageUri(pkg: Package): string { 95 | const idMapping = this.customPackageMapping[pkg.id]; 96 | 97 | if (idMapping && idMapping.uri) { 98 | return idMapping.uri; 99 | } 100 | 101 | const packageName = pkg.getName(); 102 | const nameMapping = this.customPackageMapping[packageName]; 103 | if (nameMapping && nameMapping.uri) { 104 | return nameMapping.uri; 105 | } 106 | 107 | return null; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/libs/ontouml2gufo/prefix_functions.ts: -------------------------------------------------------------------------------- 1 | import { Package } from '@libs/ontouml'; 2 | import { Ontouml2Gufo, normalizeName } from './'; 3 | 4 | import _ from 'lodash'; 5 | 6 | export const DefaultPrefixes = { 7 | gufo: 'http://purl.org/nemo/gufo#', 8 | rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 9 | rdfs: 'http://www.w3.org/2000/01/rdf-schema#', 10 | owl: 'http://www.w3.org/2002/07/owl#', 11 | xsd: 'http://www.w3.org/2001/XMLSchema#' 12 | }; 13 | 14 | export const getPrefixes = (ontouml2gufo: Ontouml2Gufo) => { 15 | return { 16 | ...getBasePrefix(ontouml2gufo), 17 | ...getPackagePrefixes(ontouml2gufo), 18 | ...DefaultPrefixes 19 | }; 20 | }; 21 | 22 | export const getBasePrefix = (ontouml2gufo: Ontouml2Gufo) => { 23 | const { baseIri, basePrefix } = ontouml2gufo.options; 24 | let prefix = {}; 25 | 26 | if (basePrefix && basePrefix.trim().length > 0) { 27 | prefix[basePrefix] = `${baseIri}#`; 28 | } else { 29 | prefix[''] = `${baseIri}#`; 30 | } 31 | 32 | return prefix; 33 | }; 34 | 35 | export const getPackagePrefixes = (ontouml2gufo: Ontouml2Gufo) => { 36 | if (!ontouml2gufo.options.prefixPackages) { 37 | return {}; 38 | } 39 | 40 | const prefixes = {}; 41 | const packages = ontouml2gufo.model.getAllPackages(); 42 | 43 | for (const pkg of packages) { 44 | const prefix = getPackagePrefix(ontouml2gufo, pkg); 45 | const uri = getPackageUri(ontouml2gufo, pkg); 46 | prefixes[prefix] = uri; 47 | } 48 | 49 | return prefixes; 50 | }; 51 | 52 | export const getPackagePrefix = (ontouml2gufo: Ontouml2Gufo, pkg: Package): string => { 53 | const customPrefix = ontouml2gufo.options.getCustomPackagePrefix(pkg); 54 | if (customPrefix) { 55 | return customPrefix; 56 | } 57 | 58 | if (ontouml2gufo.options.prefixPackages) { 59 | let prefix: string = normalizeName(pkg.getNameOrId()); 60 | prefix = prefix.charAt(0).toLowerCase() + prefix.slice(1); 61 | return prefix; 62 | } 63 | 64 | return ''; 65 | }; 66 | 67 | export const getPackageUri = (ontouml2gufo: Ontouml2Gufo, pkg: Package): string => { 68 | const customUri = ontouml2gufo.options.getCustomPackageUri(pkg); 69 | if (customUri) { 70 | return customUri; 71 | } 72 | 73 | const { options } = ontouml2gufo; 74 | 75 | if (options.prefixPackages) { 76 | let uriSuffix: string = pkg.getName(); 77 | uriSuffix = _.kebabCase(uriSuffix); 78 | 79 | return `${options.baseIri}/${uriSuffix}#`; 80 | } 81 | 82 | return ''; 83 | }; 84 | -------------------------------------------------------------------------------- /src/libs/ontouml2owl/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ontouml2owl'; 2 | -------------------------------------------------------------------------------- /src/libs/service.ts: -------------------------------------------------------------------------------- 1 | import { ServiceIssue } from './'; 2 | 3 | /** 4 | * An interface to be implemented by services processing OntoUML projects. 5 | * 6 | * **ATTENTION**: every service implementation is expected to include a constructor 7 | * with the following signature: 8 | * constructor(project: Project, options?: ServiceOptions) 9 | */ 10 | export interface Service { 11 | // I tried, but it is not possible to add to the interface a signature 12 | // for the constructor of an implementation class 13 | run(): { result: any; issues?: ServiceIssue[] }; 14 | } 15 | -------------------------------------------------------------------------------- /src/libs/service_issue.ts: -------------------------------------------------------------------------------- 1 | import { ServiceIssueSeverity } from './'; 2 | 3 | /** 4 | * An interface that describes issue objects. Issues are designed to support the description of problems identified during the 5 | * execution of service. 6 | * 7 | * @field id: unique identifier of an issue in the context of a service request 8 | * @field code: code that identifies a single issue type 9 | * @field severity: severity level of the issue 10 | * @field title: human-readable title that is equal to all occurrences of a certain issue type 11 | * @field description: human-readable description of an issue that is specific to a single occurrence of an issue type 12 | * @field data: data related to the issue that may be used on the identification of the issue's source and its resolution 13 | */ 14 | export interface ServiceIssue { 15 | id: string; 16 | code: string; 17 | severity: ServiceIssueSeverity; 18 | title: string; 19 | description: string; 20 | data: any; 21 | } 22 | -------------------------------------------------------------------------------- /src/libs/service_issue_severity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * An enumeration that identifies the different degrees of severity of an issue. 3 | */ 4 | export enum ServiceIssueSeverity { 5 | ERROR = 'error', 6 | WARNING = 'warning', 7 | INCOMPLETE = 'incomplete', 8 | INFO = 'info' 9 | } 10 | -------------------------------------------------------------------------------- /src/libs/service_options.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * An interface that describes option objects. Options are designed as generic objects that communicate preferences from a client 3 | * to a service for processing an OntoUML project. 4 | */ 5 | export interface ServiceOptions { 6 | [key: string]: any; 7 | } 8 | -------------------------------------------------------------------------------- /src/libs/verification/constants.ts: -------------------------------------------------------------------------------- 1 | export enum VerificationIssueCode { 2 | class_identity_provider_specialization = 'class_identity_provider_specialization', 3 | class_missing_nature_restrictions = 'class_missing_nature_restrictions', 4 | class_missing_identity_provider = 'class_missing_identity_provider', 5 | class_missing_is_extensional = 'class_missing_is_extensional', 6 | class_missing_is_powertype = 'class_missing_is_powertype', 7 | class_missing_order = 'class_missing_order', 8 | class_multiple_identity_providers = 'class_multiple_identity_providers', 9 | class_not_unique_stereotype = 'class_not_unique_stereotype', 10 | class_invalid_ontouml_stereotype = 'class_invalid_ontouml_stereotype', 11 | class_non_enumeration_with_literals = 'class_non_enumeration_with_literals', 12 | class_enumeration_with_properties = 'class_enumeration_with_properties', 13 | class_incompatible_natures = 'class_incompatible_natures', 14 | generalization_inconsistent_specialization = 'generalization_inconsistent_specialization', 15 | generalization_incompatible_natures = 'generalization_incompatible_natures', 16 | generalization_incompatible_enumeration = 'generalization_incompatible_enumeration', 17 | generalization_incompatible_datatype = 'generalization_incompatible_datatype', 18 | generalization_incompatible_class_rigidity = 'generalization_incompatible_class_rigidity', 19 | generalization_incompatible_class_sortality = 'generalization_incompatible_class_sortality', 20 | generalization_incompatible_general_and_specific_types = 'generalization_incompatible_general_and_specific_types', 21 | generalization_circular = 'generalization_circular', 22 | generalization_incompatible_relation_type = 'generalization_incompatible_relation_type', 23 | relation_multiple_stereotypes = 'relation_multiple_stereotypes', 24 | relation_missing_is_read_only = 'relation_missing_is_read_only', 25 | relation_improper_derivation = 'relation_improper_derivation' 26 | } 27 | -------------------------------------------------------------------------------- /src/libs/verification/generalization_set_verification.ts: -------------------------------------------------------------------------------- 1 | import { GeneralizationSet } from '@libs/ontouml'; 2 | import { VerificationIssue } from './'; 3 | 4 | export class GeneralizationSetVerification { 5 | static verifyGeneralizationSet(_generalizationSet: GeneralizationSet): VerificationIssue[] { 6 | const foundIssues: VerificationIssue[] = []; 7 | return foundIssues; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/libs/verification/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | export * from './verification_issue'; 3 | export * from './ontouml_verification'; 4 | export * from './class_verification'; 5 | export * from './generalization_set_verification'; 6 | export * from './generalization_verification'; 7 | export * from './literal_verification'; 8 | export * from './package_verification'; 9 | export * from './project_verification'; 10 | export * from './property_verification'; 11 | export * from './relation_verification'; 12 | export * from './utils'; 13 | -------------------------------------------------------------------------------- /src/libs/verification/literal_verification.ts: -------------------------------------------------------------------------------- 1 | import { Literal } from '@libs/ontouml'; 2 | import { VerificationIssue } from './'; 3 | 4 | export class LiteralVerification { 5 | static verifyLiteral(_literal: Literal): VerificationIssue[] { 6 | const foundIssues: VerificationIssue[] = []; 7 | return foundIssues; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/libs/verification/ontouml_verification.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Class, 3 | Generalization, 4 | GeneralizationSet, 5 | Literal, 6 | ModelElement, 7 | Package, 8 | Project, 9 | Property, 10 | Relation 11 | } from '@libs/ontouml'; 12 | import { 13 | VerificationIssue, 14 | ClassVerification, 15 | GeneralizationVerification, 16 | GeneralizationSetVerification, 17 | LiteralVerification, 18 | PackageVerification, 19 | ProjectVerification, 20 | PropertyVerification, 21 | RelationVerification 22 | } from '@libs/verification'; 23 | import { Service, ServiceOptions } from './..'; 24 | import _ from 'lodash'; 25 | 26 | export interface VerificationOptions extends ServiceOptions {} 27 | 28 | /** 29 | * Utility class for perform syntactical model verification 30 | * 31 | * @author Claudenir Fonseca 32 | * @author Lucas Bassetti 33 | */ 34 | export class OntoumlVerification implements Service { 35 | elementToVerify: ModelElement | Project; 36 | options: VerificationOptions; 37 | issues: VerificationIssue[]; 38 | 39 | constructor(project: Project, options?: Partial); 40 | constructor(elementToVerify: ModelElement, options?: Partial); 41 | constructor(input: ModelElement | Project, options?: Partial) { 42 | this.options = options || null; 43 | this.issues = []; 44 | this.elementToVerify = input; 45 | } 46 | 47 | run(): { result: VerificationIssue[] } { 48 | return { 49 | result: this.issues = OntoumlVerification.verify(this.elementToVerify) 50 | }; 51 | } 52 | 53 | static verify(element: ModelElement | Project): VerificationIssue[] { 54 | switch (element && element.constructor) { 55 | case Class: 56 | return ClassVerification.verifyClass(element as Class); 57 | case GeneralizationSet: 58 | return GeneralizationSetVerification.verifyGeneralizationSet(element as GeneralizationSet); 59 | case Generalization: 60 | return GeneralizationVerification.verifyGeneralization(element as Generalization); 61 | case Literal: 62 | return LiteralVerification.verifyLiteral(element as Literal); 63 | case Package: 64 | return PackageVerification.verifyPackage(element as Package); 65 | case Project: 66 | return ProjectVerification.verifyProject(element as Project); 67 | case Property: 68 | return PropertyVerification.verifyProperty(element as Property); 69 | case Relation: 70 | return RelationVerification.verifyRelation(element as Relation); 71 | default: 72 | throw new Error(`Unexpected element to be verified.`); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/libs/verification/package_verification.ts: -------------------------------------------------------------------------------- 1 | import { ModelElement, Package } from '@libs/ontouml'; 2 | import { VerificationIssue, OntoumlVerification } from './'; 3 | import _ from 'lodash'; 4 | 5 | export class PackageVerification { 6 | static verifyPackage(_package: Package): VerificationIssue[] { 7 | let foundIssues: VerificationIssue[] = []; 8 | 9 | _package 10 | .getContents() 11 | .forEach((element: ModelElement) => (foundIssues = _.concat(foundIssues, OntoumlVerification.verify(element)))); 12 | 13 | return foundIssues; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/libs/verification/project_verification.ts: -------------------------------------------------------------------------------- 1 | import { Project, ModelElement } from '@libs/ontouml'; 2 | import { VerificationIssue, OntoumlVerification } from './'; 3 | import _ from 'lodash'; 4 | 5 | export class ProjectVerification { 6 | static verifyProject(project: Project): VerificationIssue[] { 7 | let foundIssues: VerificationIssue[] = []; 8 | const model = project.model; 9 | 10 | if (model) { 11 | foundIssues = _.concat(foundIssues, OntoumlVerification.verify(model)); 12 | } 13 | 14 | return foundIssues; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/libs/verification/property_verification.ts: -------------------------------------------------------------------------------- 1 | import { Property } from '@libs/ontouml'; 2 | import { VerificationIssue } from './'; 3 | 4 | export class PropertyVerification { 5 | static verifyProperty(_property: Property): VerificationIssue[] { 6 | const foundIssues: VerificationIssue[] = []; 7 | return foundIssues; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/libs/verification/relation_verification.ts: -------------------------------------------------------------------------------- 1 | import { Relation } from '@libs/ontouml'; 2 | import { VerificationIssue } from './'; 3 | 4 | export class RelationVerification { 5 | static verifyRelation(_relation: Relation): VerificationIssue[] { 6 | const foundIssues: VerificationIssue[] = []; 7 | return foundIssues; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/libs/verification/utils.ts: -------------------------------------------------------------------------------- 1 | function pushItemsToArrayIfNotNull(array: T[], ...issues: T[]): void { 2 | for (const issue of issues) { 3 | if (issue) { 4 | array.push(issue); 5 | } 6 | } 7 | } 8 | 9 | export const utils = { 10 | pushItemsToArrayIfNotNull 11 | }; 12 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "lib": ["es2020"], 5 | "module": "es2020", 6 | "moduleResolution": "node", 7 | "allowSyntheticDefaultImports": true, 8 | "allowJs": true, 9 | "importHelpers": true, 10 | "alwaysStrict": true, 11 | "sourceMap": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "noImplicitReturns": true, 15 | "resolveJsonModule": true, 16 | "typeRoots": ["./@types", "./node_modules/@types"], 17 | "baseUrl": ".", 18 | "paths": { 19 | "@test-models/*": ["__tests__/test_models/*"], 20 | "@constants/*": ["src/constants/*"], 21 | "@error/*": ["src/error/*"], 22 | "@libs/*": ["src/libs/*"], 23 | "@utils/*": ["src/utils/*"], 24 | "@resources/*": ["resources/*"] 25 | } 26 | }, 27 | "include": ["src/**/*", "@types/**/*", "__tests__/**/*"] 28 | } 29 | -------------------------------------------------------------------------------- /tsconfig.release.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": "./src", 5 | "outDir": "./dist", 6 | "allowJs": false, 7 | "declaration": true, 8 | "emitDeclarationOnly": true, 9 | "removeComments": true, 10 | "strict": true 11 | }, 12 | "include": ["src/**/*"] 13 | } 14 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": ["node_modules/tslint-microsoft-contrib"], 3 | "extends": ["tslint-microsoft-contrib/recommended", "tslint-config-prettier"], 4 | "rules": { 5 | "no-unused-variable": true, 6 | "import-name": false, 7 | "mocha-no-side-effect-code": false, 8 | "missing-jsdoc": false, 9 | "no-relative-imports": false, 10 | "export-name": false, 11 | "promise-function-async": false, 12 | "no-void-expression": false, 13 | "no-redundant-jsdoc": false, 14 | "prefer-type-cast": false, 15 | "max-func-body-length": false, 16 | "typedef": [true, "parameter", "arrow-parameter", "property-declaration", "member-variable-declaration"] 17 | } 18 | } 19 | --------------------------------------------------------------------------------