mxrb 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.de-DE.md +108 -0
- data/README.md +172 -0
- data/README.pt-BR.md +109 -0
- data/bin/mxrb +1613 -0
- data/docs/README.md +10 -0
- data/docs/de-DE/README.md +24 -0
- data/docs/de-DE/architectural-patterns.md +26 -0
- data/docs/de-DE/architectural-standard.md +48 -0
- data/docs/de-DE/architecture.md +76 -0
- data/docs/de-DE/compiler.md +162 -0
- data/docs/de-DE/conventions.md +19 -0
- data/docs/de-DE/design-system.md +52 -0
- data/docs/de-DE/entity-dsl.md +53 -0
- data/docs/de-DE/native-runtime-quality-report.md +74 -0
- data/docs/de-DE/oql-sql.md +211 -0
- data/docs/de-DE/platform-api-integration.md +36 -0
- data/docs/de-DE/platform-operations.md +243 -0
- data/docs/de-DE/project-structure.md +32 -0
- data/docs/de-DE/ruby-first-roadmap.md +116 -0
- data/docs/de-DE/scaffolds.md +59 -0
- data/docs/de-DE/semantic-refactoring.md +56 -0
- data/docs/de-DE/team-server.md +33 -0
- data/docs/de-DE/validation-matrix.md +64 -0
- data/docs/de-DE/vetclinic-acceptance.md +24 -0
- data/docs/de-DE/writing.md +138 -0
- data/docs/en-US/README.md +24 -0
- data/docs/en-US/architectural-patterns.md +151 -0
- data/docs/en-US/architectural-standard.md +89 -0
- data/docs/en-US/architecture.md +170 -0
- data/docs/en-US/compiler.md +157 -0
- data/docs/en-US/conventions.md +82 -0
- data/docs/en-US/design-system.md +163 -0
- data/docs/en-US/entity-dsl.md +53 -0
- data/docs/en-US/native-runtime-quality-report.md +73 -0
- data/docs/en-US/oql-sql.md +201 -0
- data/docs/en-US/platform-api-integration.md +36 -0
- data/docs/en-US/platform-operations.md +244 -0
- data/docs/en-US/project-structure.md +49 -0
- data/docs/en-US/ruby-first-roadmap.md +186 -0
- data/docs/en-US/scaffolds.md +57 -0
- data/docs/en-US/semantic-refactoring.md +198 -0
- data/docs/en-US/team-server.md +32 -0
- data/docs/en-US/validation-matrix.md +257 -0
- data/docs/en-US/vetclinic-acceptance.md +23 -0
- data/docs/en-US/writing.md +655 -0
- data/docs/pt-BR/README.md +24 -0
- data/docs/pt-BR/architectural-patterns.md +25 -0
- data/docs/pt-BR/architectural-standard.md +533 -0
- data/docs/pt-BR/architecture.md +300 -0
- data/docs/pt-BR/compiler.md +162 -0
- data/docs/pt-BR/conventions.md +19 -0
- data/docs/pt-BR/design-system.md +65 -0
- data/docs/pt-BR/entity-dsl.md +116 -0
- data/docs/pt-BR/native-runtime-quality-report.md +73 -0
- data/docs/pt-BR/oql-sql.md +208 -0
- data/docs/pt-BR/platform-api-integration.md +36 -0
- data/docs/pt-BR/platform-operations.md +260 -0
- data/docs/pt-BR/project-structure.md +32 -0
- data/docs/pt-BR/ruby-first-roadmap.md +239 -0
- data/docs/pt-BR/scaffolds.md +104 -0
- data/docs/pt-BR/semantic-refactoring.md +55 -0
- data/docs/pt-BR/team-server.md +59 -0
- data/docs/pt-BR/validation-matrix.md +86 -0
- data/docs/pt-BR/vetclinic-acceptance.md +50 -0
- data/docs/pt-BR/writing.md +177 -0
- data/examples/sudoku_evaluation.rb +14 -0
- data/examples/sudoku_functional_test.rb +28 -0
- data/lib/mxrb/architecture/graph.rb +124 -0
- data/lib/mxrb/architecture/validator.rb +98 -0
- data/lib/mxrb/benchmark.rb +33 -0
- data/lib/mxrb/compare.rb +390 -0
- data/lib/mxrb/compiler/adapter.rb +96 -0
- data/lib/mxrb/compiler/artifact_document_compiler.rb +102 -0
- data/lib/mxrb/compiler/artifact_materializer.rb +53 -0
- data/lib/mxrb/compiler/client_model_materializer.rb +42 -0
- data/lib/mxrb/compiler/code_action_document_compiler.rb +64 -0
- data/lib/mxrb/compiler/code_action_materializer.rb +35 -0
- data/lib/mxrb/compiler/code_action_type_compiler.rb +32 -0
- data/lib/mxrb/compiler/combo_box_bundle_compiler.rb +314 -0
- data/lib/mxrb/compiler/compatibility_analyzer.rb +169 -0
- data/lib/mxrb/compiler/constants_materializer.rb +111 -0
- data/lib/mxrb/compiler/data_grid_bundle_compiler.rb +290 -0
- data/lib/mxrb/compiler/database_connector_action_compiler.rb +280 -0
- data/lib/mxrb/compiler/deployment_asset_copier.rb +60 -0
- data/lib/mxrb/compiler/deployment_bootstrapper.rb +208 -0
- data/lib/mxrb/compiler/deployment_materializer.rb +43 -0
- data/lib/mxrb/compiler/deployment_metadata.rb +64 -0
- data/lib/mxrb/compiler/domain_document_compiler.rb +153 -0
- data/lib/mxrb/compiler/domain_model_materializer.rb +35 -0
- data/lib/mxrb/compiler/domain_security_compiler.rb +82 -0
- data/lib/mxrb/compiler/gallery_bundle_compiler.rb +190 -0
- data/lib/mxrb/compiler/generic_widget_bundle_compiler.rb +281 -0
- data/lib/mxrb/compiler/image_bundle_compiler.rb +216 -0
- data/lib/mxrb/compiler/java_proxy_generator.rb +509 -0
- data/lib/mxrb/compiler/legacy_data_grid_compiler.rb +267 -0
- data/lib/mxrb/compiler/legacy_page_builder.rb +287 -0
- data/lib/mxrb/compiler/mda.rb +99 -0
- data/lib/mxrb/compiler/microflow_document_compiler.rb +85 -0
- data/lib/mxrb/compiler/microflow_materializer.rb +48 -0
- data/lib/mxrb/compiler/microflow_node_compiler.rb +250 -0
- data/lib/mxrb/compiler/model_package.rb +116 -0
- data/lib/mxrb/compiler/model_values.rb +67 -0
- data/lib/mxrb/compiler/nanoflow_program_compiler.rb +483 -0
- data/lib/mxrb/compiler/navigation_document_compiler.rb +93 -0
- data/lib/mxrb/compiler/packager.rb +100 -0
- data/lib/mxrb/compiler/page_bundle_builder.rb +56 -0
- data/lib/mxrb/compiler/page_bundle_compiler.rb +2004 -0
- data/lib/mxrb/compiler/page_document_compiler.rb +77 -0
- data/lib/mxrb/compiler/portable_packager.rb +356 -0
- data/lib/mxrb/compiler/project_jar_archive.rb +84 -0
- data/lib/mxrb/compiler/project_jar_builder.rb +121 -0
- data/lib/mxrb/compiler/project_materializer.rb +139 -0
- data/lib/mxrb/compiler/project_model_orderer.rb +52 -0
- data/lib/mxrb/compiler/runtime_data_types.rb +31 -0
- data/lib/mxrb/compiler/runtime_model_schema.rb +90 -0
- data/lib/mxrb/compiler/schemas/runtime-10.24.0.73019.json +1052 -0
- data/lib/mxrb/compiler/schemas/runtime-11.json +1215 -0
- data/lib/mxrb/compiler/schemas/runtime-6.10.8.json +1148 -0
- data/lib/mxrb/compiler/schemas/runtime-7.17.0.json +1144 -0
- data/lib/mxrb/compiler/schemas/runtime-7.5.0.json +1215 -0
- data/lib/mxrb/compiler/schemas/runtime-9.6.1.29396.json +868 -0
- data/lib/mxrb/compiler/schemas/system-model-10.24.0.73019.b64 +1135 -0
- data/lib/mxrb/compiler/schemas/system-model-11.12.1.b64 +815 -0
- data/lib/mxrb/compiler/schemas/system-model-6.10.8.b64 +497 -0
- data/lib/mxrb/compiler/schemas/system-model-7.17.0.b64 +519 -0
- data/lib/mxrb/compiler/schemas/system-model-7.5.0.b64 +504 -0
- data/lib/mxrb/compiler/schemas/system-model-9.6.1.29396.b64 +816 -0
- data/lib/mxrb/compiler/security_materializer.rb +104 -0
- data/lib/mxrb/compiler/settings_document_compiler.rb +45 -0
- data/lib/mxrb/compiler/settings_materializer.rb +25 -0
- data/lib/mxrb/compiler/source_model.rb +128 -0
- data/lib/mxrb/compiler/system_model_seed.rb +88 -0
- data/lib/mxrb/compiler/system_queue_materializer.rb +54 -0
- data/lib/mxrb/compiler/system_text_materializer.rb +49 -0
- data/lib/mxrb/compiler/translation_materializer.rb +95 -0
- data/lib/mxrb/compiler/web_bundle_builder.rb +155 -0
- data/lib/mxrb/compiler/web_list_data_source.rb +139 -0
- data/lib/mxrb/compiler/web_operation_compiler.rb +614 -0
- data/lib/mxrb/compiler/web_shell_materializer.rb +194 -0
- data/lib/mxrb/compiler/widget_package_extractor.rb +63 -0
- data/lib/mxrb/doctor.rb +116 -0
- data/lib/mxrb/dsl/builder.rb +1636 -0
- data/lib/mxrb/errors.rb +18 -0
- data/lib/mxrb/evaluation.rb +131 -0
- data/lib/mxrb/exporter.rb +1716 -0
- data/lib/mxrb/frontend/migrator.rb +775 -0
- data/lib/mxrb/functional.rb +307 -0
- data/lib/mxrb/github/annotator.rb +161 -0
- data/lib/mxrb/initializer.rb +257 -0
- data/lib/mxrb/integrity/validator.rb +136 -0
- data/lib/mxrb/io/bson_codec.rb +145 -0
- data/lib/mxrb/io/mpr_file.rb +558 -0
- data/lib/mxrb/io/mxunit_codec.rb +42 -0
- data/lib/mxrb/marketplace.rb +380 -0
- data/lib/mxrb/model/association.rb +98 -0
- data/lib/mxrb/model/attribute.rb +100 -0
- data/lib/mxrb/model/connector.rb +17 -0
- data/lib/mxrb/model/design_materializer.rb +133 -0
- data/lib/mxrb/model/design_migration.rb +126 -0
- data/lib/mxrb/model/design_system.rb +111 -0
- data/lib/mxrb/model/domain_model.rb +51 -0
- data/lib/mxrb/model/entity.rb +180 -0
- data/lib/mxrb/model/menu.rb +38 -0
- data/lib/mxrb/model/microflow.rb +100 -0
- data/lib/mxrb/model/module.rb +142 -0
- data/lib/mxrb/model/navigation.rb +127 -0
- data/lib/mxrb/model/page.rb +410 -0
- data/lib/mxrb/model/project.rb +187 -0
- data/lib/mxrb/model/unit.rb +48 -0
- data/lib/mxrb/module_initializer.rb +75 -0
- data/lib/mxrb/official_marketplace/content_api.rb +292 -0
- data/lib/mxrb/official_marketplace/dependency_resolver.rb +329 -0
- data/lib/mxrb/official_marketplace/lifecycle.rb +367 -0
- data/lib/mxrb/official_marketplace/module_package_importer.rb +318 -0
- data/lib/mxrb/official_marketplace/widget_package_installer.rb +414 -0
- data/lib/mxrb/official_marketplace.rb +720 -0
- data/lib/mxrb/oql/analyzer.rb +155 -0
- data/lib/mxrb/oql/index_advisor.rb +85 -0
- data/lib/mxrb/oql/plan_analyzer.rb +185 -0
- data/lib/mxrb/oql/server.rb +132 -0
- data/lib/mxrb/oql/sql_server_plan_analyzer.rb +190 -0
- data/lib/mxrb/oql/sql_server_workload_analyzer.rb +80 -0
- data/lib/mxrb/oql/workload_analyzer.rb +175 -0
- data/lib/mxrb/oql/workload_baseline.rb +60 -0
- data/lib/mxrb/oql.rb +424 -0
- data/lib/mxrb/project_lifecycle.rb +76 -0
- data/lib/mxrb/protocols/plan.rb +86 -0
- data/lib/mxrb/protocols.rb +123 -0
- data/lib/mxrb/runtime/database_workspace.rb +677 -0
- data/lib/mxrb/runtime/docker_executor.rb +41 -0
- data/lib/mxrb/runtime/docker_workspace.rb +29 -0
- data/lib/mxrb/runtime/executor.rb +169 -0
- data/lib/mxrb/runtime/java_locator.rb +26 -0
- data/lib/mxrb/runtime/native.rb +474 -0
- data/lib/mxrb/runtime/sql_server_database.rb +146 -0
- data/lib/mxrb/runtime/toolchain.rb +82 -0
- data/lib/mxrb/scaffold/cli.rb +113 -0
- data/lib/mxrb/scaffold/generator.rb +246 -0
- data/lib/mxrb/scaffold/help.rb +80 -0
- data/lib/mxrb/scaffold/page_templates.rb +54 -0
- data/lib/mxrb/scaffold/recipes.rb +198 -0
- data/lib/mxrb/scaffold/registry.rb +82 -0
- data/lib/mxrb/scaffold/templates.rb +723 -0
- data/lib/mxrb/scaffold/transaction.rb +84 -0
- data/lib/mxrb/schema/tables.rb +55 -0
- data/lib/mxrb/semantic/analyzer.rb +473 -0
- data/lib/mxrb/semantic/batch_plan.rb +68 -0
- data/lib/mxrb/semantic/domain_mutator.rb +419 -0
- data/lib/mxrb/semantic/embedder.rb +51 -0
- data/lib/mxrb/semantic/extractor.rb +290 -0
- data/lib/mxrb/semantic/index.rb +623 -0
- data/lib/mxrb/semantic/inliner.rb +216 -0
- data/lib/mxrb/semantic/mover.rb +153 -0
- data/lib/mxrb/semantic/onnx_embedder.rb +34 -0
- data/lib/mxrb/semantic/remover.rb +70 -0
- data/lib/mxrb/semantic/renamer.rb +211 -0
- data/lib/mxrb/semantic/tfidf_embedder.rb +46 -0
- data/lib/mxrb/semantic/vec_store.rb +75 -0
- data/lib/mxrb/team_server.rb +390 -0
- data/lib/mxrb/templates/project/10.24.0.73019.json +32 -0
- data/lib/mxrb/templates/project/11.12.1.json +32 -0
- data/lib/mxrb/templates/project/6.10.8.json +50 -0
- data/lib/mxrb/templates/project/7.17.0.json +50 -0
- data/lib/mxrb/templates/project/7.5.0.json +50 -0
- data/lib/mxrb/templates/project/9.6.1.29396.json +50 -0
- data/lib/mxrb/version.rb +5 -0
- data/lib/mxrb/widget_package.rb +338 -0
- data/lib/mxrb/widget_synchronizer.rb +31 -0
- data/lib/mxrb/writer.rb +3775 -0
- data/lib/mxrb.rb +188 -0
- data/marketplace/catalog.json +10 -0
- data/marketplace/modules/shared-kernel/domain/README.md +4 -0
- data/marketplace/modules/shared-kernel/module.rb +5 -0
- data/marketplace/modules/shared-kernel/mxrb-module.json +9 -0
- metadata +447 -0
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
5
|
+
module Mxrb
|
|
6
|
+
module Compiler
|
|
7
|
+
# Materializes the subset of Studio Pro generated Java proxies required by project sources.
|
|
8
|
+
# Proxy syntax is intentionally kept together so generated Java remains auditable.
|
|
9
|
+
# rubocop:disable Metrics/AbcSize, Metrics/ClassLength, Metrics/CyclomaticComplexity
|
|
10
|
+
# rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
11
|
+
class JavaProxyGenerator
|
|
12
|
+
include ModelValues
|
|
13
|
+
|
|
14
|
+
TYPE_MAP = {
|
|
15
|
+
'DomainModels$StringAttributeType' => 'java.lang.String',
|
|
16
|
+
'DomainModels$HashStringAttributeType' => 'java.lang.String',
|
|
17
|
+
'DomainModels$HashedStringAttributeType' => 'java.lang.String',
|
|
18
|
+
'DomainModels$IntegerAttributeType' => 'java.lang.Integer',
|
|
19
|
+
'DomainModels$LongAttributeType' => 'java.lang.Long',
|
|
20
|
+
'DomainModels$AutoNumberAttributeType' => 'java.lang.Long',
|
|
21
|
+
'DomainModels$DecimalAttributeType' => 'java.math.BigDecimal',
|
|
22
|
+
'DomainModels$BooleanAttributeType' => 'java.lang.Boolean',
|
|
23
|
+
'DomainModels$DateTimeAttributeType' => 'java.util.Date',
|
|
24
|
+
'DomainModels$BinaryAttributeType' => 'byte[]'
|
|
25
|
+
}.freeze
|
|
26
|
+
|
|
27
|
+
CONSTANT_TYPE_MAP = {
|
|
28
|
+
'DataTypes$StringType' => 'java.lang.String', 'DataTypes$IntegerType' => 'java.lang.Long',
|
|
29
|
+
'DataTypes$DecimalType' => 'java.math.BigDecimal', 'DataTypes$BooleanType' => 'java.lang.Boolean',
|
|
30
|
+
'DataTypes$DateTimeType' => 'java.util.Date'
|
|
31
|
+
}.freeze
|
|
32
|
+
|
|
33
|
+
def initialize(mpr_path, project_root: File.dirname(File.expand_path(mpr_path)))
|
|
34
|
+
@source = SourceModel.read(mpr_path)
|
|
35
|
+
@project_root = File.expand_path(project_root)
|
|
36
|
+
@system_seed = SystemModelSeed.for(@source.version)
|
|
37
|
+
@domain_units = @source.units_of('DomainModels$DomainModel') + [system_domain_unit]
|
|
38
|
+
@entities = entity_index
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def generate
|
|
42
|
+
generated = write_user_actions_registrar ? 1 : 0
|
|
43
|
+
source_text = java_source_text
|
|
44
|
+
generated += microflow_modules.count do |mod|
|
|
45
|
+
microflows_referenced?(source_text, mod) && write_microflows(mod, source_text)
|
|
46
|
+
end
|
|
47
|
+
source_text = java_source_text if generated.positive?
|
|
48
|
+
requested = requested_entities(source_text)
|
|
49
|
+
entity_count = requested.count { |name| write_entity(name) }
|
|
50
|
+
generated += entity_count
|
|
51
|
+
source_text = java_source_text if entity_count.positive?
|
|
52
|
+
generated += enumeration_units.count { |unit| referenced?(source_text, proxy_name(unit)) && write_enum(unit) }
|
|
53
|
+
generated += constant_modules.count { |mod| constants_referenced?(source_text, mod) && write_constants(mod) }
|
|
54
|
+
generated
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def java_source_text
|
|
60
|
+
Dir.glob(File.join(@project_root, 'javasource', '**', '*.java')).sort.map { File.read(_1) }.join("\n")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def write_user_actions_registrar
|
|
64
|
+
classes = user_action_classes
|
|
65
|
+
return false if classes.empty?
|
|
66
|
+
|
|
67
|
+
path = File.join(@project_root, 'javasource', 'system', 'UserActionsRegistrar.java')
|
|
68
|
+
write_missing(path, user_actions_registrar_source(classes))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def user_action_classes
|
|
72
|
+
@source.units_of('JavaActions$JavaAction').filter_map do |unit|
|
|
73
|
+
name = document_name(unit.document).to_s
|
|
74
|
+
package_name = java_package(unit.module_name)
|
|
75
|
+
source = File.join(@project_root, 'javasource', package_name, 'actions', "#{name}.java")
|
|
76
|
+
"#{package_name}.actions.#{name}" if !name.empty? && File.file?(source)
|
|
77
|
+
end.sort.uniq
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def user_actions_registrar_source(classes)
|
|
81
|
+
registrations = classes.map do |class_name|
|
|
82
|
+
" registrator.registerUserAction(#{class_name}.class);"
|
|
83
|
+
end.join("\n")
|
|
84
|
+
<<~JAVA
|
|
85
|
+
// Generated natively by mxrb from Java action documents and sources.
|
|
86
|
+
package system;
|
|
87
|
+
|
|
88
|
+
public class UserActionsRegistrar {
|
|
89
|
+
public void registerActions(com.mendix.core.actionmanagement.IActionRegistrator registrator) {
|
|
90
|
+
#{registrations}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
JAVA
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def entity_index
|
|
97
|
+
@domain_units.each_with_object({}) do |unit, index|
|
|
98
|
+
array(unit.document['Entities']).each do |entity|
|
|
99
|
+
index[entity_qualified_name(unit, entity)] = [unit, entity]
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def system_domain_unit
|
|
105
|
+
document = @system_seed.domain_document
|
|
106
|
+
SourceModel::Unit.new(
|
|
107
|
+
id: identifier(document['$ID']), container_id: SystemModelSeed::MODULE_ID,
|
|
108
|
+
containment: 'DomainModel', document:, module_name: 'System'
|
|
109
|
+
)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def entity_qualified_name(unit, entity)
|
|
113
|
+
entity['QualifiedName'] || "#{unit.module_name}.#{entity.fetch('Name')}"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def entity_name(entity) = entity['Name'] || entity['UnqualifiedName']
|
|
117
|
+
|
|
118
|
+
def requested_entities(text)
|
|
119
|
+
result = @entities.keys.select { referenced?(text, java_proxy_name(_1)) }.to_set
|
|
120
|
+
loop do
|
|
121
|
+
before = result.length
|
|
122
|
+
result.to_a.each { add_entity_dependencies(_1, result) }
|
|
123
|
+
break if result.length == before
|
|
124
|
+
end
|
|
125
|
+
result.to_a
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def add_entity_dependencies(name, result)
|
|
129
|
+
unit, entity = @entities.fetch(name)
|
|
130
|
+
parent = generalization(entity)
|
|
131
|
+
result << parent if @entities.key?(parent)
|
|
132
|
+
associations_for(unit, entity).each do |association|
|
|
133
|
+
child = association_child_qualified(unit, association)
|
|
134
|
+
result << child if @entities.key?(child)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def referenced?(text, java_name)
|
|
139
|
+
text.match?(/(?<![A-Za-z0-9_])#{Regexp.escape(java_name)}(?![A-Za-z0-9_])/)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def java_proxy_name(qualified)
|
|
143
|
+
mod, name = qualified.split('.', 2)
|
|
144
|
+
"#{java_package(mod)}.proxies.#{name}"
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def proxy_name(unit) = "#{java_package(unit.module_name)}.proxies.#{document_name(unit.document)}"
|
|
148
|
+
def java_package(mod) = mod.to_s.downcase
|
|
149
|
+
|
|
150
|
+
def write_entity(qualified)
|
|
151
|
+
unit, entity = @entities.fetch(qualified)
|
|
152
|
+
path = proxy_path(unit.module_name, "#{entity_name(entity)}.java")
|
|
153
|
+
write_missing(path, entity_source(unit, entity))
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def entity_source(unit, entity) # rubocop:disable Metrics/MethodLength
|
|
157
|
+
name = entity_name(entity)
|
|
158
|
+
qualified = entity_qualified_name(unit, entity)
|
|
159
|
+
java_name = java_proxy_name(qualified)
|
|
160
|
+
parent = generalization(entity)
|
|
161
|
+
local_parent = @entities.key?(parent) ? java_proxy_name(parent) : nil
|
|
162
|
+
members = attributes(entity).map { [_1['Name'], _1['Name']] }
|
|
163
|
+
members += associations_for(unit, entity).map do |association|
|
|
164
|
+
[association_name(association), association_qualified_name(unit, association)]
|
|
165
|
+
end
|
|
166
|
+
inheritance = if local_parent
|
|
167
|
+
"extends #{local_parent}"
|
|
168
|
+
else
|
|
169
|
+
'implements com.mendix.systemwideinterfaces.core.IEntityProxy'
|
|
170
|
+
end
|
|
171
|
+
storage = local_parent ? '' : <<~JAVA
|
|
172
|
+
private final com.mendix.systemwideinterfaces.core.IMendixObject mendixObject;
|
|
173
|
+
private final com.mendix.systemwideinterfaces.core.IContext context;
|
|
174
|
+
JAVA
|
|
175
|
+
constructor_body = local_parent ? 'super(context, mendixObject);' : root_constructor_body
|
|
176
|
+
accessors = attributes(entity).map { attribute_methods(unit, _1) }.join("\n")
|
|
177
|
+
accessors += associations_for(unit, entity).map { association_methods(unit, _1) }.join("\n")
|
|
178
|
+
base_methods = local_parent ? '' : base_entity_methods
|
|
179
|
+
<<~JAVA
|
|
180
|
+
// Generated natively by mxrb from the MPR model.
|
|
181
|
+
package #{java_package(unit.module_name)}.proxies;
|
|
182
|
+
|
|
183
|
+
public class #{name} #{inheritance} {
|
|
184
|
+
#{storage}
|
|
185
|
+
public static final java.lang.String entityName = "#{qualified}";
|
|
186
|
+
public enum MemberNames {
|
|
187
|
+
#{members.map { |member, meta| "#{member}(\"#{meta}\")" }.join(",\n ")};
|
|
188
|
+
private final java.lang.String metaName;
|
|
189
|
+
MemberNames(java.lang.String value) { metaName = value; }
|
|
190
|
+
@java.lang.Override public java.lang.String toString() { return metaName; }
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
public #{name}(com.mendix.systemwideinterfaces.core.IContext context) {
|
|
194
|
+
this(context, com.mendix.core.Core.instantiate(context, entityName));
|
|
195
|
+
}
|
|
196
|
+
protected #{name}(com.mendix.systemwideinterfaces.core.IContext context,
|
|
197
|
+
com.mendix.systemwideinterfaces.core.IMendixObject mendixObject) {
|
|
198
|
+
#{constructor_body}
|
|
199
|
+
}
|
|
200
|
+
public static #{java_name} initialize(com.mendix.systemwideinterfaces.core.IContext context,
|
|
201
|
+
com.mendix.systemwideinterfaces.core.IMendixObject mendixObject) {
|
|
202
|
+
return new #{java_name}(context, mendixObject);
|
|
203
|
+
}
|
|
204
|
+
public static #{java_name} load(com.mendix.systemwideinterfaces.core.IContext context,
|
|
205
|
+
com.mendix.systemwideinterfaces.core.IMendixIdentifier id) throws com.mendix.core.CoreException {
|
|
206
|
+
return initialize(context, com.mendix.core.Core.retrieveId(context, id));
|
|
207
|
+
}
|
|
208
|
+
#{accessors}
|
|
209
|
+
#{base_methods}
|
|
210
|
+
public static java.lang.String getType() { return entityName; }
|
|
211
|
+
}
|
|
212
|
+
JAVA
|
|
213
|
+
end # rubocop:enable Metrics/MethodLength
|
|
214
|
+
|
|
215
|
+
def root_constructor_body
|
|
216
|
+
<<~JAVA.chomp
|
|
217
|
+
if (mendixObject == null)
|
|
218
|
+
throw new java.lang.IllegalArgumentException("The given object cannot be null.");
|
|
219
|
+
this.mendixObject = mendixObject;
|
|
220
|
+
this.context = context;
|
|
221
|
+
JAVA
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def base_entity_methods
|
|
225
|
+
<<~JAVA
|
|
226
|
+
@java.lang.Override public com.mendix.systemwideinterfaces.core.IMendixObject getMendixObject() { return mendixObject; }
|
|
227
|
+
public com.mendix.systemwideinterfaces.core.IContext getContext() { return context; }
|
|
228
|
+
@java.lang.Override public boolean equals(Object other) {
|
|
229
|
+
return other == this || (other != null && getClass().equals(other.getClass()) &&
|
|
230
|
+
mendixObject.equals(((com.mendix.systemwideinterfaces.core.IEntityProxy) other).getMendixObject()));
|
|
231
|
+
}
|
|
232
|
+
@java.lang.Override public int hashCode() { return mendixObject.hashCode(); }
|
|
233
|
+
JAVA
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def attribute_methods(unit, attribute)
|
|
237
|
+
name = attribute['Name']
|
|
238
|
+
type = attribute['NewType'] || attribute['Type'] || {}
|
|
239
|
+
java_type = attribute_java_type(unit, type)
|
|
240
|
+
read = if type['$Type'] == 'DomainModels$EnumerationAttributeType'
|
|
241
|
+
enum_attribute_reader(name, java_type)
|
|
242
|
+
else
|
|
243
|
+
"return (#{java_type}) getMendixObject().getValue(context, MemberNames.#{name}.toString());"
|
|
244
|
+
end
|
|
245
|
+
value = if type['$Type'] == 'DomainModels$EnumerationAttributeType'
|
|
246
|
+
'value == null ? null : value.toString()'
|
|
247
|
+
else
|
|
248
|
+
'value'
|
|
249
|
+
end
|
|
250
|
+
<<~JAVA
|
|
251
|
+
public final #{java_type} get#{name}() { return get#{name}(getContext()); }
|
|
252
|
+
public final #{java_type} get#{name}(com.mendix.systemwideinterfaces.core.IContext context) {
|
|
253
|
+
#{read}
|
|
254
|
+
}
|
|
255
|
+
public final void set#{name}(#{java_type} value) { set#{name}(getContext(), value); }
|
|
256
|
+
public final void set#{name}(com.mendix.systemwideinterfaces.core.IContext context, #{java_type} value) {
|
|
257
|
+
getMendixObject().setValue(context, MemberNames.#{name}.toString(), #{value});
|
|
258
|
+
}
|
|
259
|
+
JAVA
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def enum_attribute_reader(name, java_type)
|
|
263
|
+
"Object value = getMendixObject().getValue(context, MemberNames.#{name}.toString());\n" \
|
|
264
|
+
" return value == null ? null : #{java_type}.valueOf((java.lang.String) value);"
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def attribute_java_type(unit, type)
|
|
268
|
+
unless type['$Type'] == 'DomainModels$EnumerationAttributeType'
|
|
269
|
+
return TYPE_MAP.fetch(type['$Type'],
|
|
270
|
+
'java.lang.Object')
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
reference = type['Enumeration'].to_s
|
|
274
|
+
reference = "#{unit.module_name}.#{reference}" unless reference.include?('.')
|
|
275
|
+
java_proxy_name(reference)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def associations_for(unit, entity)
|
|
279
|
+
id = identifier(entity['$ID'])
|
|
280
|
+
associations = array(unit.document['Associations']) + array(unit.document['CrossAssociations'])
|
|
281
|
+
associations.select { identifier(_1['ParentPointer']) == id }
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def association_methods(unit, association)
|
|
285
|
+
name = association_name(association)
|
|
286
|
+
child_type = association_child_type(unit, association)
|
|
287
|
+
return reference_methods(name, child_type) if association['Type'] == 'Reference'
|
|
288
|
+
return '' unless association['Type'] == 'ReferenceSet'
|
|
289
|
+
|
|
290
|
+
<<~JAVA
|
|
291
|
+
public final java.util.List<#{child_type}> get#{name}() throws com.mendix.core.CoreException { return get#{name}(getContext()); }
|
|
292
|
+
public final java.util.List<#{child_type}> get#{name}(com.mendix.systemwideinterfaces.core.IContext context) throws com.mendix.core.CoreException {
|
|
293
|
+
java.util.List<com.mendix.systemwideinterfaces.core.IMendixIdentifier> ids = getMendixObject().getValue(context, MemberNames.#{name}.toString());
|
|
294
|
+
if (ids == null) return java.util.Collections.emptyList();
|
|
295
|
+
java.util.List<#{child_type}> result = new java.util.ArrayList<>();
|
|
296
|
+
for (com.mendix.systemwideinterfaces.core.IMendixIdentifier id : ids) result.add(#{child_type}.load(context, id));
|
|
297
|
+
return result;
|
|
298
|
+
}
|
|
299
|
+
public final void set#{name}(java.util.List<#{child_type}> values) { set#{name}(getContext(), values); }
|
|
300
|
+
public final void set#{name}(com.mendix.systemwideinterfaces.core.IContext context, java.util.List<#{child_type}> values) {
|
|
301
|
+
java.util.List<com.mendix.systemwideinterfaces.core.IMendixIdentifier> ids = values == null ? null : values.stream()
|
|
302
|
+
.map(value -> value.getMendixObject().getId()).collect(java.util.stream.Collectors.toList());
|
|
303
|
+
getMendixObject().setValue(context, MemberNames.#{name}.toString(), ids);
|
|
304
|
+
}
|
|
305
|
+
JAVA
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def association_name(association)
|
|
309
|
+
association['Name'] || association['UnqualifiedName'] || association['QualifiedName'].to_s.split('.').last
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def association_qualified_name(unit, association)
|
|
313
|
+
association['QualifiedName'] || "#{unit.module_name}.#{association_name(association)}"
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
def association_child_type(unit, association)
|
|
317
|
+
qualified = association_child_qualified(unit, association)
|
|
318
|
+
unless qualified.empty?
|
|
319
|
+
return java_proxy_name(qualified) if @entities.key?(qualified)
|
|
320
|
+
|
|
321
|
+
return 'com.mendix.systemwideinterfaces.core.IEntityProxy'
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
'com.mendix.systemwideinterfaces.core.IEntityProxy'
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def association_child_qualified(unit, association)
|
|
328
|
+
qualified = association['Child'].to_s
|
|
329
|
+
return qualified unless qualified.empty?
|
|
330
|
+
|
|
331
|
+
child = entity_by_id(association['ChildPointer'])
|
|
332
|
+
child ? entity_qualified_name(unit, child) : ''
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def reference_methods(name, child_type)
|
|
336
|
+
<<~JAVA
|
|
337
|
+
public final #{child_type} get#{name}() throws com.mendix.core.CoreException { return get#{name}(getContext()); }
|
|
338
|
+
public final #{child_type} get#{name}(com.mendix.systemwideinterfaces.core.IContext context) throws com.mendix.core.CoreException {
|
|
339
|
+
com.mendix.systemwideinterfaces.core.IMendixIdentifier id = getMendixObject().getValue(context, MemberNames.#{name}.toString());
|
|
340
|
+
return id == null ? null : #{child_type}.load(context, id);
|
|
341
|
+
}
|
|
342
|
+
public final void set#{name}(#{child_type} value) { set#{name}(getContext(), value); }
|
|
343
|
+
public final void set#{name}(com.mendix.systemwideinterfaces.core.IContext context, #{child_type} value) {
|
|
344
|
+
getMendixObject().setValue(context, MemberNames.#{name}.toString(), value == null ? null : value.getMendixObject().getId());
|
|
345
|
+
}
|
|
346
|
+
JAVA
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
def entity_by_id(id)
|
|
350
|
+
wanted = identifier(id)
|
|
351
|
+
@entities.values.map(&:last).find { identifier(_1['$ID']) == wanted }
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def identifier(value)
|
|
355
|
+
value.respond_to?(:data) ? value.data : value.to_s
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def attributes(entity) = array(entity['Attributes'])
|
|
359
|
+
def generalization(entity) = entity.dig('MaybeGeneralization', 'Generalization').to_s
|
|
360
|
+
|
|
361
|
+
def enumeration_units
|
|
362
|
+
source_units = @source.units_of('Enumerations$Enumeration')
|
|
363
|
+
system_units = @system_seed.package.documents.filter_map do |document|
|
|
364
|
+
next unless document['$Type'] == 'Enumerations$Enumeration'
|
|
365
|
+
|
|
366
|
+
SourceModel::Unit.new(
|
|
367
|
+
id: identifier(document['$ID']), container_id: SystemModelSeed::MODULE_ID,
|
|
368
|
+
containment: 'AllDocuments', document:, module_name: 'System'
|
|
369
|
+
)
|
|
370
|
+
end
|
|
371
|
+
source_units + system_units
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
def write_enum(unit)
|
|
375
|
+
names = array(unit.document['Values']).map { _1['Name'] }
|
|
376
|
+
name = document_name(unit.document)
|
|
377
|
+
source = <<~JAVA
|
|
378
|
+
// Generated natively by mxrb from the MPR model.
|
|
379
|
+
package #{java_package(unit.module_name)}.proxies;
|
|
380
|
+
public enum #{name} { #{names.join(', ')} }
|
|
381
|
+
JAVA
|
|
382
|
+
write_missing(proxy_path(unit.module_name, "#{name}.java"), source)
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
def document_name(document) = document['Name'] || document['UnqualifiedName']
|
|
386
|
+
|
|
387
|
+
def constant_modules = @source.units_of('Constants$Constant').map(&:module_name).uniq
|
|
388
|
+
|
|
389
|
+
def constants_referenced?(text, mod)
|
|
390
|
+
referenced?(text, "#{java_package(mod)}.proxies.constants.Constants")
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
def write_constants(mod)
|
|
394
|
+
units = @source.units_of('Constants$Constant').select { _1.module_name == mod }
|
|
395
|
+
methods = units.map do |unit|
|
|
396
|
+
type = CONSTANT_TYPE_MAP.fetch(unit.document.dig('Type', '$Type'), 'java.lang.Object')
|
|
397
|
+
name = unit.document['Name']
|
|
398
|
+
"public static #{type} get#{name}() { return (#{type}) " \
|
|
399
|
+
"com.mendix.core.Core.getConfiguration().getConstantValue(\"#{mod}.#{name}\"); }"
|
|
400
|
+
end.join("\n ")
|
|
401
|
+
source = <<~JAVA
|
|
402
|
+
// Generated natively by mxrb from the MPR model.
|
|
403
|
+
package #{java_package(mod)}.proxies.constants;
|
|
404
|
+
public final class Constants {
|
|
405
|
+
private Constants() {}
|
|
406
|
+
#{methods}
|
|
407
|
+
}
|
|
408
|
+
JAVA
|
|
409
|
+
write_missing(proxy_path(mod, 'constants', 'Constants.java'), source)
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
def microflow_modules = @source.units_of('Microflows$Microflow').map(&:module_name).uniq
|
|
413
|
+
|
|
414
|
+
def microflows_referenced?(text, mod)
|
|
415
|
+
referenced?(text, "#{java_package(mod)}.proxies.microflows.Microflows")
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
def write_microflows(mod, text)
|
|
419
|
+
units = @source.units_of('Microflows$Microflow').select { _1.module_name == mod }
|
|
420
|
+
selected = units.select { |unit| referenced_microflow?(text, unit.document['Name']) }
|
|
421
|
+
return false if selected.empty?
|
|
422
|
+
|
|
423
|
+
methods = selected.map { microflow_method(_1) }.join("\n")
|
|
424
|
+
source = <<~JAVA
|
|
425
|
+
// Generated natively by mxrb from the MPR model.
|
|
426
|
+
package #{java_package(mod)}.proxies.microflows;
|
|
427
|
+
public final class Microflows {
|
|
428
|
+
private Microflows() {}
|
|
429
|
+
#{methods}
|
|
430
|
+
}
|
|
431
|
+
JAVA
|
|
432
|
+
write_missing(proxy_path(mod, 'microflows', 'Microflows.java'), source)
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
def referenced_microflow?(text, name)
|
|
436
|
+
method = lower_camel(name)
|
|
437
|
+
text.match?(/\bMicroflows\.#{Regexp.escape(method)}\b/)
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
def microflow_method(unit)
|
|
441
|
+
parameters = microflow_parameters(unit.document)
|
|
442
|
+
declarations = parameters.map do |parameter|
|
|
443
|
+
"#{java_data_type(parameter['VariableType'])} _#{lower_camel(parameter['Name'])}"
|
|
444
|
+
end
|
|
445
|
+
arguments = parameters.map do |parameter|
|
|
446
|
+
".withParam(\"#{parameter['Name']}\", _#{lower_camel(parameter['Name'])})"
|
|
447
|
+
end.join
|
|
448
|
+
return_type = java_data_type(unit.document['MicroflowReturnType'], return_type: true)
|
|
449
|
+
result = microflow_result(unit.document['MicroflowReturnType'])
|
|
450
|
+
<<~JAVA
|
|
451
|
+
public static #{return_type} #{lower_camel(unit.document['Name'])}(
|
|
452
|
+
com.mendix.systemwideinterfaces.core.IContext context#{declarations.empty? ? '' : ",\n #{declarations.join(",\n ")}"}) {
|
|
453
|
+
Object result = com.mendix.core.Core.microflowCall("#{unit.module_name}.#{unit.document['Name']}")#{arguments}.execute(context);
|
|
454
|
+
#{result}
|
|
455
|
+
}
|
|
456
|
+
JAVA
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
def microflow_parameters(document)
|
|
460
|
+
array(document.dig('ObjectCollection', 'Objects')).select do |object|
|
|
461
|
+
object['$Type'] == 'Microflows$MicroflowParameter'
|
|
462
|
+
end
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def java_data_type(type, return_type: false)
|
|
466
|
+
case type&.fetch('$Type', nil)
|
|
467
|
+
when 'DataTypes$BooleanType' then return_type ? 'boolean' : 'java.lang.Boolean'
|
|
468
|
+
when 'DataTypes$IntegerType', 'DataTypes$LongType' then 'java.lang.Long'
|
|
469
|
+
when 'DataTypes$DecimalType' then 'java.math.BigDecimal'
|
|
470
|
+
when 'DataTypes$DateTimeType' then 'java.util.Date'
|
|
471
|
+
when 'DataTypes$StringType' then 'java.lang.String'
|
|
472
|
+
when 'DataTypes$ObjectType' then java_proxy_name(type['Entity'])
|
|
473
|
+
when 'DataTypes$VoidType', nil then 'void'
|
|
474
|
+
else 'java.lang.Object'
|
|
475
|
+
end
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
def microflow_result(type)
|
|
479
|
+
case type&.fetch('$Type', nil)
|
|
480
|
+
when 'DataTypes$BooleanType' then 'return (boolean) result;'
|
|
481
|
+
when 'DataTypes$ObjectType'
|
|
482
|
+
proxy = java_proxy_name(type['Entity'])
|
|
483
|
+
"return result == null ? null : #{proxy}.initialize(context, " \
|
|
484
|
+
'(com.mendix.systemwideinterfaces.core.IMendixObject) result);'
|
|
485
|
+
when 'DataTypes$VoidType', nil then 'return;'
|
|
486
|
+
else "return (#{java_data_type(type, return_type: true)}) result;"
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
def lower_camel(value)
|
|
491
|
+
value.to_s.sub(/\A./, &:downcase)
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
def proxy_path(mod, *parts)
|
|
495
|
+
File.join(@project_root, 'javasource', java_package(mod), 'proxies', *parts)
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
def write_missing(path, contents)
|
|
499
|
+
return false if File.exist?(path)
|
|
500
|
+
|
|
501
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
502
|
+
File.write(path, contents)
|
|
503
|
+
true
|
|
504
|
+
end
|
|
505
|
+
end
|
|
506
|
+
# rubocop:enable Metrics/AbcSize, Metrics/ClassLength, Metrics/CyclomaticComplexity
|
|
507
|
+
# rubocop:enable Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
508
|
+
end
|
|
509
|
+
end
|