com.nedap.archie.flattener.AnnotationsAndOverlaysFlattener Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tools Show documentation
Show all versions of tools Show documentation
tools that operate on the archie reference models and archetype object model
The newest version!
package com.nedap.archie.flattener;
import com.nedap.archie.aom.Archetype;
import com.nedap.archie.aom.OperationalTemplate;
import com.nedap.archie.aom.ResourceAnnotations;
import com.nedap.archie.aom.rmoverlay.RmOverlay;
import com.nedap.archie.aom.rmoverlay.RmAttributeVisibility;
import java.util.LinkedHashMap;
import java.util.Map;
public class AnnotationsAndOverlaysFlattener {
public void flattenAnnotations(Archetype parent, Archetype child, Archetype result) {
if( (isAnnotationsEmpty(parent) && isAnnotationsEmpty(child))) {
return;
}
ResourceAnnotations resultAnnotation = ensureAnnotationsPresent(result);
Map>> resultDocumentation = resultAnnotation.getDocumentation();
mergeInAnnotations(parent, resultDocumentation);
mergeInAnnotations(child, resultDocumentation);
}
public void flattenRmOverlay(Archetype parent, Archetype child, Archetype result) {
if( (isRmOverlayEmpty(parent) && isRmOverlayEmpty(child))) {
return;
}
RmOverlay resultOverlay = ensureRmOverlayPresent(result);
Map resultVisibility = resultOverlay.getRmVisibility();
mergeInVisibility(parent, resultVisibility);
mergeInVisibility(child, resultVisibility);
}
public void addVisibilityWithPathPrefix(String pathPrefix, Archetype archetype, OperationalTemplate result) {
if(isRmOverlayEmpty(archetype)) {
return;
}
ensureRmOverlayPresent(result);
Map rmVisibilityToBeMergedIn = archetype.getRmOverlay().getRmVisibility();
for(String path: rmVisibilityToBeMergedIn.keySet()) {
String newPath = ensureNoSlashAtEnd(pathPrefix) + path;
result.getRmOverlay().getRmVisibility().put(newPath, (RmAttributeVisibility) rmVisibilityToBeMergedIn.get(path).clone());
}
}
public void addAnnotationsWithPathPrefix(String pathPrefix, Archetype archetype, OperationalTemplate result) {
if(isAnnotationsEmpty(archetype)) {
return;
}
Map>> documentationToBeMergedIn = archetype.getAnnotations().getDocumentation();
for(String language: documentationToBeMergedIn.keySet()) {
Map> languageAnnotationsToBeMergedIn = documentationToBeMergedIn.get(language);
for(String path: languageAnnotationsToBeMergedIn.keySet()) {
String newPath = ensureNoSlashAtEnd(pathPrefix) + path;
merge(language, newPath, languageAnnotationsToBeMergedIn.get(path), result);
}
}
}
/* visibility private methods */
private void mergeInVisibility(Archetype toBeMergedIn, Map resultVisibility) {
if(!isRmOverlayEmpty(toBeMergedIn)) {
RmOverlay toBeMergedInRmOverlay = toBeMergedIn.getRmOverlay();
Map toBeMergedInRmVisibility = toBeMergedInRmOverlay.getRmVisibility();
mergeVisibility(resultVisibility, toBeMergedInRmVisibility);
}
}
private void mergeVisibility(Map resultVisibility, Map toBeMergedInRmVisibility) {
for(String path:toBeMergedInRmVisibility.keySet()) {
RmAttributeVisibility toBeMergedInVisibility = toBeMergedInRmVisibility.get(path);
RmAttributeVisibility targetVisibility = resultVisibility.get(path);
if(targetVisibility == null) {
targetVisibility = (RmAttributeVisibility) toBeMergedInVisibility.clone();
resultVisibility.put(path, targetVisibility);
} else {
//two visibilities. One should override the other?
targetVisibility = (RmAttributeVisibility) toBeMergedInVisibility.clone();
resultVisibility.put(path, targetVisibility);
}
}
}
private RmOverlay ensureRmOverlayPresent(Archetype result) {
if(result.getRmOverlay() == null) {
result.setRmOverlay(new RmOverlay());
}
if(result.getRmOverlay().getRmVisibility() == null) {
result.getRmOverlay().setRmVisibility(new LinkedHashMap<>());
}
return result.getRmOverlay();
}
private boolean isRmOverlayEmpty(Archetype archetype) {
return archetype.getRmOverlay() == null
|| archetype.getRmOverlay().getRmVisibility() == null
|| archetype.getRmOverlay().getRmVisibility().isEmpty();
}
/* annotations private methods */
private ResourceAnnotations ensureAnnotationsPresent(Archetype result) {
ResourceAnnotations resultAnnotation = result.getAnnotations();
if(resultAnnotation == null) {
resultAnnotation = new ResourceAnnotations();
result.setAnnotations(resultAnnotation);
}
if(resultAnnotation.getDocumentation() == null) {
resultAnnotation.setDocumentation(new LinkedHashMap<>());
}
return resultAnnotation;
}
/**
* Merge the annotations of the given archetype ino the given result documentation
* @param toBeMergedIn the archetype for which the annotation should be merged in
* @param resultDocumentation the resulting documentation in which the archetypes are to be merged in. Must be a non-null editable Map.
*/
private void mergeInAnnotations(Archetype toBeMergedIn, Map>> resultDocumentation) {
if(!isAnnotationsEmpty(toBeMergedIn)) {
ResourceAnnotations toBeMergedInAnnotations = toBeMergedIn.getAnnotations();
Map>> toBeMergedInDocumentation = toBeMergedInAnnotations.getDocumentation();
mergeDocumentation(resultDocumentation, toBeMergedInDocumentation);
}
}
/**
* Merges the second map into the first one, overwriting all keys already present, adding keys when not present.
* Structure of maps must be:
* language -> path -> annotation name -> annotation value
* eg:
* nl -> /path/to/something -> design note -> text of design note
* @param resultDocumentation the resulting documentation to be updated. Must be an empty map
* @param documentationToBeMergedIn the documentation to be copied in the resulting documentation
*/
private void mergeDocumentation(Map>> resultDocumentation, Map>> documentationToBeMergedIn) {
for(String language:documentationToBeMergedIn.keySet()) {
Map> languageAnnotationsToBeMergedIn = documentationToBeMergedIn.get(language);
Map> resultLanguageAnnotations = resultDocumentation.get(language);
if(resultLanguageAnnotations == null) {
resultLanguageAnnotations = new LinkedHashMap<>();
resultDocumentation.put(language, resultLanguageAnnotations);
}
for(String path: languageAnnotationsToBeMergedIn.keySet()) {
Map pathAnnotationsToBeMergedIn = languageAnnotationsToBeMergedIn.get(path);
Map resultPathAnnotations = resultLanguageAnnotations.get(path);
if(resultPathAnnotations == null) {
resultPathAnnotations = new LinkedHashMap<>();
resultLanguageAnnotations.put(path, resultPathAnnotations);
}
resultPathAnnotations.putAll(pathAnnotationsToBeMergedIn);
}
}
}
private boolean isAnnotationsEmpty(Archetype archetype) {
return archetype.getAnnotations() == null ||
archetype.getAnnotations().getDocumentation() == null ||
archetype.getAnnotations().getDocumentation().isEmpty();
}
private void merge(String language, String newPath, Map annotationsMap, OperationalTemplate result) {
ResourceAnnotations annotations = ensureAnnotationsPresent(result);
Map> languageMap = annotations.getDocumentation().get(language);
if(languageMap == null) {
languageMap = new LinkedHashMap<>();
annotations.getDocumentation().put(language, languageMap);
}
Map existingAnnotations = languageMap.get(newPath);
if(existingAnnotations == null) {
existingAnnotations = new LinkedHashMap<>(annotationsMap);
languageMap.put(newPath, existingAnnotations);
} else {
existingAnnotations.putAll(annotationsMap);
}
}
/* shared private methods */
private String ensureNoSlashAtEnd(String pathPrefix) {
if(pathPrefix.endsWith("/")) {
return pathPrefix.substring(0, pathPrefix.length() - 1);
}
return pathPrefix;
}
}