Skip to content

Commit 8849d14

Browse files
Merge pull request #80 from TechnologyBrewery/78-enable-metamodel-extension
#78 Added functionality for accessing the current ModelInstanceRepository implementation outside of the GenerationContext
2 parents b4164fe + 504014b commit 8849d14

File tree

2 files changed

+67
-4
lines changed

2 files changed

+67
-4
lines changed

fermenter-mda/src/main/java/org/technologybrewery/fermenter/mda/metamodel/ModelInstanceRepositoryManager.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,43 @@ public final class ModelInstanceRepositoryManager {
1010

1111
private static ThreadLocal<Map<String, Object>> threadBoundInstance = ThreadLocal.withInitial(HashMap::new);
1212

13+
private static final String ABSTRACT_MODEL_INSTANCE_REPOSITORY_CLASS_NAME =
14+
"org.technologybrewery.fermenter.mda.metamodel.AbstractModelInstanceRepository";
15+
1316
private ModelInstanceRepositoryManager() {
1417
// prevent private instantiation of all static class
1518
}
1619

1720
/**
18-
* Adds a repository. Only one repository of each type will be kept.
21+
* Sets a repository as the repository implementation for its own class and any super
22+
* classes if present. This enables downstream projects to safely extend upstream
23+
* {@link ModelInstanceRepository}'s without breaking existing calls to getRepository().
24+
*
25+
* For example, given the classes:
26+
* MIR_A implements AbstractModelInstanceRepository
27+
* MIR_B extends MIR_A
28+
* MIR_C extends MIR_B
29+
*
30+
* When the repository is set using setRepository(MIR_C). Then following calls to
31+
* getRepository would all return the MIR_C instance:
32+
* getMetamodelRepository(MIR_A.class) -> MIR_C
33+
* getMetamodelRepository(MIR_B.class) -> MIR_C
34+
* getMetamodelRepository(MIR_C.class) -> MIR_C
1935
*
20-
* @param respository
36+
* @param repository
2137
* repository to add
2238
*/
23-
public static void setRepository(ModelInstanceRepository respository) {
39+
public static void setRepository(ModelInstanceRepository repository) {
2440
Map<String, Object> instanceMap = threadBoundInstance.get();
25-
instanceMap.put(respository.getClass().toString(), respository);
41+
42+
instanceMap.put(repository.getClass().toString(), repository);
43+
Class<?> repositorySuperClass = repository.getClass().getSuperclass();
44+
45+
// Add an entry for all superclasses of the repository
46+
while (!repositorySuperClass.getName().equals(ABSTRACT_MODEL_INSTANCE_REPOSITORY_CLASS_NAME)) {
47+
instanceMap.put(repositorySuperClass.toString(), repository);
48+
repositorySuperClass = repositorySuperClass.getSuperclass();
49+
}
2650
}
2751

2852
/**

fermenter-mda/src/test/java/org/technologybrewery/fermenter/mda/metamodel/MetadataRepositoryManagerTest.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,27 @@ public void testOverwriteMetadataReposistory() {
6161

6262
}
6363

64+
@Test
65+
public void testMetadataRepositoryExtension() {
66+
// Set the repository to the lowest subclass
67+
TestMetadataRepository testRepositoryExtensionB = new TestMetadataRepositoryExtensionB(null);
68+
ModelInstanceRepositoryManager.setRepository(testRepositoryExtensionB);
69+
70+
// Get the repository extension with its superclass references
71+
TestMetadataRepository managedTestRespository = ModelInstanceRepositoryManager
72+
.getMetamodelRepository(TestMetadataRepository.class);
73+
assertEquals(testRepositoryExtensionB, managedTestRespository);
74+
75+
managedTestRespository = ModelInstanceRepositoryManager
76+
.getMetamodelRepository(TestMetadataRepositoryExtensionA.class);
77+
assertEquals(testRepositoryExtensionB, managedTestRespository);
78+
79+
// Get the repository extension with its current class reference
80+
managedTestRespository = ModelInstanceRepositoryManager
81+
.getMetamodelRepository(TestMetadataRepositoryExtensionB.class);
82+
assertEquals(testRepositoryExtensionB, managedTestRespository);
83+
}
84+
6485
@Test
6586
public void testClearMetadataReposistoryManager() {
6687
setNewDefaultMetadataRepository();
@@ -106,3 +127,21 @@ public void validate() {
106127
}
107128

108129
}
130+
131+
/**
132+
* Used for testing only.
133+
*/
134+
class TestMetadataRepositoryExtensionA extends TestMetadataRepository {
135+
public TestMetadataRepositoryExtensionA(ModelRepositoryConfiguration config) {
136+
super(config);
137+
}
138+
}
139+
140+
/**
141+
* Used for testing only.
142+
*/
143+
class TestMetadataRepositoryExtensionB extends TestMetadataRepositoryExtensionA {
144+
public TestMetadataRepositoryExtensionB(ModelRepositoryConfiguration config) {
145+
super(config);
146+
}
147+
}

0 commit comments

Comments
 (0)