Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.regnosys.rosetta.translate.util.SchemaMerge Maven / Gradle / Ivy
package com.regnosys.rosetta.translate.util;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.regnosys.rosetta.common.util.UrlUtils;
import com.regnosys.rosetta.translate.datamodel.Attribute;
import com.regnosys.rosetta.translate.datamodel.AttributeImpl;
import com.regnosys.rosetta.translate.datamodel.Cardinality;
import com.regnosys.rosetta.translate.datamodel.Entity;
import com.regnosys.rosetta.translate.datamodel.EntityImpl;
import com.regnosys.rosetta.translate.datamodel.ModelParser;
import com.regnosys.rosetta.translate.datamodel.NamespaceName;
import com.regnosys.rosetta.translate.datamodel.Schema;
import com.regnosys.rosetta.translate.datamodel.SchemaSerialise;
import com.regnosys.rosetta.translate.datamodel.json.CreateiQJsonSchemaParser;
public class SchemaMerge {
private final static Logger LOGGER = LoggerFactory.getLogger(SchemaMerge.class);
private final static String schemasToMergeDir = "/Users/hugohills/dev/github/REGnosys/rosetta-cdm/rosetta-source/src/main/resources/schemas/isda-create";
private final static String outputSchemaFileName = "isda-create-merged.schema";
private final static List excludedSchemaFileNames = List.of("isda-create-merged.json");
public static void main(String[] args) throws IOException {
Path schemasDir = Paths.get(schemasToMergeDir);
Pattern jsonSchemaPattern = Pattern.compile(".*json");
Stream schemasToMerge = Files.list(schemasDir)
.filter(p -> jsonSchemaPattern.matcher(p.getFileName().toString()).matches())
.filter(p -> !excludedSchemaFileNames.contains(p.getFileName().toString()));
ModelParser parser = new CreateiQJsonSchemaParser();
List schemas = schemasToMerge
.peek(System.out::println)
.map(s->parser.parseModel(UrlUtils.toUrl(s)))
.collect(Collectors.toList());
Schema merged = schemas.stream().reduce(null, SchemaMerge::mergeSchemas);
Path mergedSchemaPath = schemasDir.resolve(outputSchemaFileName);
SchemaSerialise serialise = new SchemaSerialise();
try (OutputStream newOutputStream = Files.newOutputStream(mergedSchemaPath)) {
serialise.serialiseObject(merged, newOutputStream);
} catch (Exception e) {
LOGGER.error("Failed to merge schema", e);
}
}
private static Schema mergeSchemas(Schema s1, Schema s2) {
if (s1==null) return s2;
if (s2==null) return s1;
Map mergedEntities = new IdentityHashMap<>();
Map mergedAttributesMap = new IdentityHashMap<>();
List mergedGlobals = mergeEntities(s1.getGlobalTypes(), s2.getGlobalTypes(), mergedEntities, mergedAttributesMap);
List mergedAttributes = mergeAttributes(s1.getAttributes(), s2.getAttributes(), mergedEntities, mergedAttributesMap);
return new Schema(mergedAttributes, mergedGlobals);
}
private static List mergeEntities(Collection globalTypes1, Collection globalTypes2,
Map mergedEntities, Map mergedAttributes) {
List result = new ArrayList<>();
Map> collect = Stream.concat(globalTypes1.stream(), globalTypes2.stream()).collect(Collectors.groupingBy(a->a.getName(), LinkedHashMap::new, Collectors.toList()));
collect.entrySet().stream().forEach(e->{
List atts = e.getValue();
if (atts.size()==1) {
result.add(atts.get(0));
}
else {
result.add(mergeEntity(atts, mergedEntities, mergedAttributes));
}
});
return result;
}
private static Entity mergeEntity(List ents, Map mergedEntities, Map mergedAttributes) {
if (ents.size()!=2) {
throw new RuntimeException("One of the inpus schemas had duplicate Entities named "+ents.get(0).getName());
}
Entity ent1 = ents.get(0);
Entity ent2 = ents.get(1);
return mergeType(ent1, ent2, mergedEntities, mergedAttributes);
}
private static List mergeAttributes(Collection attributes1, Collection attributes2, Map mergedEntities, Map mergedAttributes) {
List result = new ArrayList<>();
Map> collect = Stream.concat(attributes1.stream(), attributes2.stream()).collect(Collectors.groupingBy(a->a.getName(), LinkedHashMap::new, Collectors.toList()));
collect.entrySet().stream().forEach(e->{
List atts = e.getValue();
if (atts.size()==1) {
result.add(atts.get(0));
}
else {
result.add(mergeAttribute(atts, mergedEntities, mergedAttributes));
}
});
return result;
}
private static Attribute mergeAttribute(List atts, Map mergedEntities, Map mergedAttributes) {
if (atts.size()!=2) {
throw new RuntimeException("One of the inpus schemas had duplicate attributes named "+atts.get(0).getName());
}
Attribute att1 = atts.get(0);
Attribute att2 = atts.get(1);
if (mergedAttributes.containsKey(att1)) {
return mergedAttributes.get(att1);
}
AttributeImpl attributeImpl = new AttributeImpl(att1.getName(), Cardinality.max(att1.getCardinality(), att2.getCardinality()), mergeType(att1.getType(), att2.getType(), mergedEntities, mergedAttributes));
mergedAttributes.put(att1, attributeImpl);
return attributeImpl;
}
private static Entity mergeType(Entity type, Entity type2, Map mergedEntities, Map mergedAttributes) {
NamespaceName name = type.getName();
NamespaceName name2 = type2.getName();
if (!name.equals(name2)) {
throw new RuntimeException("schemas had differnt entities of ("+name + "|"+name2+")");
}
if (mergedEntities.containsKey(type)) {
return mergedEntities.get(type);
}
Entity mergedExtended = mergeExtended(type.getExtendedEntity(), type2.getExtendedEntity(), mergedEntities, mergedAttributes);
boolean hasValue = type.hasData() || type2.hasData();
EntityImpl e = new EntityImpl(name, mergedExtended, hasValue);
e.getAttributes().addAll(mergeAttributes(type.getAttributes(), type2.getAttributes(), mergedEntities, mergedAttributes));
mergedEntities.put(type, e);
return e;
}
private static Entity mergeExtended(Entity e1, Entity e2, Map mergedEntities, Map mergedAttributes) {
if (e1==null) return e2;
if (e2==null) return e1;
return mergeType(e1, e2, mergedEntities, mergedAttributes);
}
}