All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.regnosys.rosetta.translate.synonymmap.CardinalityChecker Maven / Gradle / Ivy

There is a newer version: 11.25.1
Show newest version
package com.regnosys.rosetta.translate.synonymmap;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.log4j.Logger;
import org.eclipse.xtext.xbase.lib.Pair;

import com.codahale.metrics.Timer;
import com.codahale.metrics.Timer.Context;
import com.regnosys.rosetta.translate.IngesterGenerator;
import com.regnosys.rosetta.translate.MappingError;
import com.regnosys.rosetta.translate.datamodel.Attribute;
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.NamespaceName;

public class CardinalityChecker {

	private final static Logger LOGGER = Logger.getLogger(CardinalityChecker.class.getName());
	
	public ListcheckCardinalities(List synonyms) {
		Timer timer = IngesterGenerator.GENERATOR_METRICS.timer("checking cardinality");
		Context time = timer.time();
		Set> checked = new HashSet<>();
		LOGGER.trace("Checking cardinality");
		Entity top = new EntityImpl(new NamespaceName("top", "TopLevel"), false);
		List errors = synonyms.stream().flatMap(s->validCardinalities(s, top, checked).stream()).collect(Collectors.toList());
		time.stop();
		return errors;
	}

	private List validCardinalities(SynonymMap s, Entity parentEntity, Set> checked) {
		Pair key = new Pair<>(s, parentEntity);
		if (checked.contains(key)) return Collections.emptyList();
		checked.add(key);
		List errors = new ArrayList<>();
        for (AttributeGroupMapping mappedGroups : s.getMappedGroups()) {
            long rosettaCardinality = mappedGroups.getGroup().getAttributePath().stream().filter(ra -> ra.isMultiple()).count();
            for (SynonymGroup sg : mappedGroups.getGroup().getSynonymGroups()) {
				for (SynonymValue path : sg.getSynonymValues()) {
					long synonymCardinality = getCardinality(parentEntity, path.getSynonymPath());
					
					
					if (rosettaCardinality>1 && synonymCardinality>0) {
						errors.add(new MappingError(MappingError.MappingErrorLevel.WARNING,
								"Ambiguous cardinality choices for path " + s.getRosetta().getName() + ":" +
                                        mappedGroups.getGroup().attsToString() + " matching " + path.getSynonymPath().toString()));
					} else if (synonymCardinality>=1 && rosettaCardinality==0) {
						errors.add(new MappingError(MappingError.MappingErrorLevel.ERROR, 
								"Invalid cardinality choices for "+ s.getRosetta().getName() +":XSD " + 
										toPath(parentEntity, path) +" is multiple while Rosetta " +
                                        toPath(s, mappedGroups.getGroup().attsToString()) + " is single "));
					}
					Entity last = path.getSynonymPath().get(path.getSynonymPath().size()-1).getEntity();
                    errors.addAll(validCardinalities(mappedGroups.getMappings(), last, checked));
				}
			}
			
		}
		
		return errors;
	}

	private String toPath(Entity parentEntity, SynonymValue path) {
		StringBuilder builder = new StringBuilder();
		builder.append(Optional.ofNullable(parentEntity).map(Entity::getName).map(Object::toString).orElse(""));
		for (Element el:path.getSynonymPath()) {
			builder.append("->");
			builder.append(el.getName());
		}
		return builder.toString();	
	}

	private String toPath(SynonymMap s, String attsToString) {
		StringBuilder builder = new StringBuilder();
		builder.append(s.getRosetta().getName());
		builder.append("->");
		builder.append(attsToString);
		return builder.toString();	
	}

	private long getCardinality(Entity parentEntity, List path) {
		Entity ent = parentEntity;
		long card=0;
		for (Element e:path) {
			if (ent!=null) {
				Optional findFirst = ent.getAllPossibleAttributes().filter(att->att.getName().equals(e.getName())).findFirst();
				if (!findFirst.isPresent()) {
					return 0;//This path is not valid from this starting entity so its cardinality is effectively 0 (but it might be from another)
				}
				Attribute link = findFirst.get();
				if (link.getCardinality()==Cardinality.MULTIPLE) {
					card++;
				}
			}
			ent = e.getEntity();
		}
		return card;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy