Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,43 @@ public final class ModelInstanceRepositoryManager {

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

private static final String ABSTRACT_MODEL_INSTANCE_REPOSITORY_CLASS_NAME =
"org.technologybrewery.fermenter.mda.metamodel.AbstractModelInstanceRepository";

private ModelInstanceRepositoryManager() {
// prevent private instantiation of all static class
}

/**
* Adds a repository. Only one repository of each type will be kept.
* Sets a repository as the repository implementation for its own class and any super
* classes if present. This enables downstream projects to safely extend upstream
* {@link ModelInstanceRepository}'s without breaking existing calls to getRepository().
*
* For example, given the classes:
* MIR_A implements AbstractModelInstanceRepository
* MIR_B extends MIR_A
* MIR_C extends MIR_B
*
* When the repository is set using setRepository(MIR_C). Then following calls to
* getRepository would all return the MIR_C instance:
* getMetamodelRepository(MIR_A.class) -> MIR_C
* getMetamodelRepository(MIR_B.class) -> MIR_C
* getMetamodelRepository(MIR_C.class) -> MIR_C
*
* @param respository
* @param repository
* repository to add
*/
public static void setRepository(ModelInstanceRepository respository) {
public static void setRepository(ModelInstanceRepository repository) {
Map<String, Object> instanceMap = threadBoundInstance.get();
instanceMap.put(respository.getClass().toString(), respository);

instanceMap.put(repository.getClass().toString(), repository);
Class<?> repositorySuperClass = repository.getClass().getSuperclass();

// Add an entry for all superclasses of the repository
while (!repositorySuperClass.getName().equals(ABSTRACT_MODEL_INSTANCE_REPOSITORY_CLASS_NAME)) {
instanceMap.put(repositorySuperClass.toString(), repository);
repositorySuperClass = repositorySuperClass.getSuperclass();
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,27 @@ public void testOverwriteMetadataReposistory() {

}

@Test
public void testMetadataRepositoryExtension() {
// Set the repository to the lowest subclass
TestMetadataRepository testRepositoryExtensionB = new TestMetadataRepositoryExtensionB(null);
ModelInstanceRepositoryManager.setRepository(testRepositoryExtensionB);

// Get the repository extension with its superclass references
TestMetadataRepository managedTestRespository = ModelInstanceRepositoryManager
.getMetamodelRepository(TestMetadataRepository.class);
assertEquals(testRepositoryExtensionB, managedTestRespository);

managedTestRespository = ModelInstanceRepositoryManager
.getMetamodelRepository(TestMetadataRepositoryExtensionA.class);
assertEquals(testRepositoryExtensionB, managedTestRespository);

// Get the repository extension with its current class reference
managedTestRespository = ModelInstanceRepositoryManager
.getMetamodelRepository(TestMetadataRepositoryExtensionB.class);
assertEquals(testRepositoryExtensionB, managedTestRespository);
}

@Test
public void testClearMetadataReposistoryManager() {
setNewDefaultMetadataRepository();
Expand Down Expand Up @@ -106,3 +127,21 @@ public void validate() {
}

}

/**
* Used for testing only.
*/
class TestMetadataRepositoryExtensionA extends TestMetadataRepository {
public TestMetadataRepositoryExtensionA(ModelRepositoryConfiguration config) {
super(config);
}
}

/**
* Used for testing only.
*/
class TestMetadataRepositoryExtensionB extends TestMetadataRepositoryExtensionA {
public TestMetadataRepositoryExtensionB(ModelRepositoryConfiguration config) {
super(config);
}
}
Loading