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

com.regnosys.rosetta.translate.HandlerWithPath Maven / Gradle / Ivy

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

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import com.regnosys.rosetta.common.translation.Mapping;
import com.regnosys.rosetta.common.translation.MappingContext;
import com.regnosys.rosetta.common.translation.MappingProcessor;
import com.regnosys.rosetta.common.translation.Path;
import com.regnosys.rosetta.common.translation.Path.PathElement;
import com.regnosys.rosetta.translate.basic.BasicParseHandler;
import com.regnosys.rosetta.translate.basic.BasicParseHandler.SetResult;
import com.rosetta.model.lib.path.RosettaPath;


/**
 * @author TomForwood
 * An element and a list of handlers that are interested at this point
 */
class HandlerWithPath {

	private final ParseHandler handler;

	/**
	 * a stack of the elements encountered since this handler was bought into the picture (by a match on a parent)
	 */
	private final Deque elementStack = new ArrayDeque<>();

	HandlerWithPath(ParseHandler handler) {
		this.handler = handler;
	}

	Deque addToStackIfNotNull(Path.PathElement element) {
		if (element != null) {
			elementStack.addLast(element);
		}
		return elementStack;
	}

	void removeLastIfExists() {
		if (!elementStack.isEmpty()) {
			elementStack.removeLast();
		}
	}

	boolean isComplexHandler() {
		return handler instanceof ROMParseHandler;
	}

	/**
	 * TODO Should add some comments what is happening here
	 *
	 * @param mappings
	 * @return
	 */
	Collection> matchingMappingProcessors(Path parentPath, MappingContext mappingContext) {
		ROMParseHandler parseHandler = (ROMParseHandler) handler;
		Collection> matchPaths = parseHandler.getMappingProcessorMatchPaths();
		MatchResult matchResult = ParserHelper.getMatchType(matchPaths, elementStack);
		
		switch (matchResult.matchType()) {
			case FULL:
			case BOTH:
					return parseHandler.getMappingProcessorForPath(matchResult.fullMatch(), parentPath, mappingContext);
			default:
				return Collections.emptyList();
		}
	}

	/**
	 * TODO Should add some comments what is happening here
	 * 
	 * @param element
	 * @param parentPath
	 * @return
	 */
	List matchingHandlers(PathElement element, Path parentPath) {
		ROMParseHandler parseHandler = (ROMParseHandler) handler;
		Deque path = addToStackIfNotNull(element);
		Collection> matchPaths = parseHandler.getHandlerMatchPaths();
		MatchResult matchResult = ParserHelper.getMatchType(matchPaths, path);
		switch (matchResult.matchType()) {
		case FULL:
			return createHandlersFromMatch(parseHandler, matchResult, parentPath);
		case BOTH:
			List handlersFromMatch = createHandlersFromMatch(parseHandler, matchResult, parentPath);
			handlersFromMatch.add(this);
			return handlersFromMatch;
		case PARTIAL:
			return Collections.singletonList(this);
		case NONE:
			return Collections.emptyList();
		default:
			throw new AssertionError("Invalid MatchResult.MatchType enum");
		}
	}

	/**
	 * TODO Should add some comments what is happening here
	 * 
	 * @param handlers
	 * @param trimmedVal
	 * @param path
	 * @return
	 */
	static List createMappings(List handlers, String trimmedVal, Path path) {
		List mappings = new ArrayList<>();
		Supplier someMultiMap = () -> false;
		for (HandlerWithPath handler : handlers) {
			if (!handler.isComplexHandler()) {
				handler.createMapping(trimmedVal, path, someMultiMap).ifPresent(mappings::add);
			}
		}
		if (mappings.isEmpty()) {
			mappings.add(new Mapping(path, trimmedVal, null, null, "Element could not be mapped to a rosettaField", someMultiMap.get(), false, false));
		}
		return mappings;
	}
	
	private List createHandlersFromMatch(ROMParseHandler parseHandler, MatchResult matchResult, Path parentPath) {
		Collection newHandlers = parseHandler.getHandlersForPath(matchResult.fullMatch(), parentPath);
		List resultHandlers = newHandlers.stream()
														  .map(ph -> new HandlerWithPath(ph))
														  .collect(Collectors.toList());
		return resultHandlers;
	}

	private Optional createMapping(String value, Path path, Supplier someMultiMap) {
		BasicParseHandler basicHandler = (BasicParseHandler) handler;
		if (basicHandler.allowsMultiple()) {
			someMultiMap = () -> true;
		}
		SetResult result = basicHandler.setValue(value);
		switch (result.getStatus()) {
			case DUPLICATE:
				// Ignore conditional mappings where the new / old values are the same
				if (basicHandler.isCondition() && result.getNewValue().equals(result.getOldValue())) {
					return Optional.empty();
				}
				return Optional.of(new Mapping(path, value, basicHandler.getRosettaPath(), result.getNewValue(),
						"Element mapped to already populated field", someMultiMap.get(), basicHandler.isCondition(), true));
			case PARSING:
				return Optional.of(new Mapping(path, value, basicHandler.getRosettaPath(), result.getNewValue(),
						"Element " + value + " could not be parsed as a " + handler.getClass().getSimpleName().replace("ParseHandler", ""),
						someMultiMap.get(), basicHandler.isCondition(), false));
			case MAPPING:
				return Optional.of(new Mapping(path, value, basicHandler.getRosettaPath(), result.getNewValue(),
						"Element " + value + " was not set due to path mapping issues",
						someMultiMap.get(), basicHandler.isCondition(), false));
			case SUCCESS:
				return Optional.of(new Mapping(path, value, basicHandler.getRosettaPath(), result.getNewValue(), null, someMultiMap.get(), basicHandler.isCondition(), false));
			default:
				throw new AssertionError("Invalid BasicParseHandler.SetResult enum");
		}
	}

	@Override
	public String toString() {
		return "HandlerWithPath [handler=" + handler 
				+ ", xmlPathsToHere=" + handler.getXmlPathsToHere() 
				+ ", rosettaPath=" + handler.getRosettaPath() 
				+ ", elementStack=" + elementStack 
				+ "]";
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy