com.gs.dmn.DMNModelRepository Maven / Gradle / Ivy
/**
* Copyright 2016 Goldman Sachs.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.gs.dmn;
import com.gs.dmn.runtime.DMNRuntimeException;
import com.gs.dmn.serialization.PrefixNamespaceMappings;
import com.gs.dmn.transformation.DMNToJavaTransformer;
import com.gs.dmn.transformation.basic.QualifiedName;
import org.apache.commons.lang3.StringUtils;
import org.omg.spec.dmn._20180521.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.bind.JAXBElement;
import java.util.*;
import java.util.stream.Collectors;
import static com.gs.dmn.serialization.DMNConstants.FEEL_12_PREFIX;
public class DMNModelRepository {
private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
private static final Logger LOGGER = LoggerFactory.getLogger(DMNModelRepository.class);
private final TDefinitions definitions;
private final PrefixNamespaceMappings prefixNamespaceMappings;
public DMNModelRepository() {
this(OBJECT_FACTORY.createTDefinitions(), new PrefixNamespaceMappings() );
}
public DMNModelRepository(TDefinitions definitions, PrefixNamespaceMappings prefixNamespaceMappings) {
this.definitions = definitions;
this.prefixNamespaceMappings = prefixNamespaceMappings;
normalize(definitions);
}
private void normalize(TDefinitions definitions) {
if (definitions != null) {
sortDRGElements(definitions.getDrgElement());
sortNamedElements(definitions.getItemDefinition());
}
}
public Set computeCachedElements(boolean cachingFlag) {
if (!cachingFlag) {
return new LinkedHashSet<>();
}
LOGGER.info("Scanning for decisions to cache ...");
Map map = new LinkedHashMap<>();
for (TDecision decision : decisions()) {
for (TInformationRequirement ir : decision.getInformationRequirement()) {
TDMNElementReference requiredDecision = ir.getRequiredDecision();
if (requiredDecision != null) {
String href = requiredDecision.getHref();
Integer counter = map.get(href);
if (counter == null) {
counter = Integer.valueOf(0);
}
counter++;
map.put(href, counter);
}
}
}
Set result = new LinkedHashSet<>();
for(Map.Entry entry: map.entrySet()) {
if (entry.getValue() > 1) {
TDecision drgElement = this.findDecisionById(entry.getKey());
if (drgElement != null) {
result.add(name(drgElement));
}
}
}
LOGGER.info(String.format("Decisions to be cached: %s", result.stream().collect(Collectors.joining(", "))));
return result;
}
public String removeSingleQuotes(String name) {
if (isQuotedName(name)) {
name = name.substring(1, name.length() - 1);
}
return name;
}
private boolean isQuotedName(String name) {
return name != null && name.startsWith("'") && name.endsWith("'");
}
public TDefinitions getDefinitions() {
return definitions;
}
public PrefixNamespaceMappings getPrefixNamespaceMappings() {
return prefixNamespaceMappings;
}
public List drgElements() {
List result = new ArrayList<>();
for (JAXBElement extends TDRGElement> jaxbElement : definitions.getDrgElement()) {
TDRGElement element = jaxbElement.getValue();
result.add(element);
}
return result;
}
public List decisions() {
List result = new ArrayList<>();
if (definitions == null) {
return result;
}
for (JAXBElement extends TDRGElement> jaxbElement : definitions.getDrgElement()) {
TDRGElement element = jaxbElement.getValue();
if (element instanceof TDecision) {
result.add((TDecision) element);
}
}
return result;
}
public List inputDatas() {
List result = new ArrayList<>();
if (definitions == null) {
return result;
}
for (JAXBElement extends TDRGElement> jaxbElement : definitions.getDrgElement()) {
TDRGElement element = jaxbElement.getValue();
if (element instanceof TInputData) {
result.add((TInputData) element);
}
}
return result;
}
public List businessKnowledgeModels() {
List result = new ArrayList<>();
if (definitions == null) {
return result;
}
for (JAXBElement extends TDRGElement> jaxbElement : definitions.getDrgElement()) {
TDRGElement element = jaxbElement.getValue();
if (element instanceof TBusinessKnowledgeModel) {
result.add((TBusinessKnowledgeModel) element);
}
}
return result;
}
public List decisionServices() {
List result = new ArrayList<>();
if (definitions == null) {
return result;
}
for (JAXBElement extends TDRGElement> jaxbElement : definitions.getDrgElement()) {
TDRGElement element = jaxbElement.getValue();
if (element instanceof TDecisionService) {
result.add((TDecisionService) element);
}
}
return result;
}
public List itemDefinitions() {
if (definitions == null) {
return new ArrayList<>();
}
return definitions.getItemDefinition();
}
public List sortItemComponent(TItemDefinition itemDefinition) {
if (itemDefinition == null || itemDefinition.getItemComponent() == null) {
return null;
}
List children = new ArrayList<>(itemDefinition.getItemComponent());
children.sort((o1, o2) -> {
if (o1 == null && o2 == null) {
return 0;
} if (o1 == null) {
return 1;
} if (o2 == null) {
return -1;
} else {
return o1.getName().compareTo(o2.getName());
}
});
return children;
}
public TItemDefinition normalize(TItemDefinition itemDefinition) {
while (true) {
TItemDefinition next = next(itemDefinition);
if (next != null) {
itemDefinition = next;
} else {
break;
}
}
return itemDefinition;
}
private TItemDefinition next(TItemDefinition itemDefinition) {
if (itemDefinition == null
|| itemDefinition.isIsCollection()
|| !isEmpty(itemDefinition.getItemComponent())
|| itemDefinition.getTypeRef() == null) {
return null;
}
return lookupItemDefinition(QualifiedName.toQualifiedName(itemDefinition.getTypeRef()));
}
private void sortDRGElements(List> result) {
result.sort(Comparator.comparing((JAXBElement extends TDRGElement> o) -> removeSingleQuotes(o.getValue().getName())));
}
public void sortNamedElements(List extends TNamedElement> result) {
result.sort(Comparator.comparing((TNamedElement o) -> removeSingleQuotes(o.getName())));
}
public TDecision findDecisionById(String href) {
for (TDecision decision : decisions()) {
if (sameId(decision, href)) {
return decision;
}
}
throw new DMNRuntimeException(String.format("Cannot find decision for href='%s'", href));
}
public TInputData findInputDataById(String href) {
for (TInputData inputData : inputDatas()) {
if (sameId(inputData, href)) {
return inputData;
}
}
throw new DMNRuntimeException(String.format("Cannot find input data for href='%s'", href));
}
public TInvocable findInvocableById(String href) {
for (TBusinessKnowledgeModel knowledgeModel : businessKnowledgeModels()) {
if (sameId(knowledgeModel, href)) {
return knowledgeModel;
}
}
for (TDecisionService service : decisionServices()) {
if (sameId(service, href)) {
return service;
}
}
throw new DMNRuntimeException(String.format("Cannot find invocable (knowledge model or decision service) for href='%s'", href));
}
public TBusinessKnowledgeModel findKnowledgeModelByName(String name) {
for (TBusinessKnowledgeModel knowledgeModel : businessKnowledgeModels()) {
if (sameName(knowledgeModel, name)) {
return knowledgeModel;
}
}
throw new DMNRuntimeException(String.format("Cannot find business knowledge model for name='%s'", name));
}
public TDecisionService findDecisionServiceByName(String name) {
for (TDecisionService service : decisionServices()) {
if (sameName(service, name)) {
return service;
}
}
throw new DMNRuntimeException(String.format("Cannot find decision service for name='%s'", name));
}
public TDRGElement findDRGElementByName(String href) {
for (TDRGElement element : drgElements()) {
if (sameName(element, href)) {
return element;
}
}
throw new DMNRuntimeException(String.format("Cannot find element for href='%s'", href));
}
public boolean sameId(TDMNElement element, String href) {
if (href.startsWith("#")) {
href = href.substring(1);
}
return element.getId().equals(href);
}
private boolean sameName(TNamedElement element, String href) {
return element.getName().equals(href);
}
public List directSubDecisions(TDRGElement element) {
List decisions = new ArrayList<>();
if (element instanceof TDecision) {
for (TInformationRequirement ir : ((TDecision) element).getInformationRequirement()) {
TDMNElementReference requiredDecision = ir.getRequiredDecision();
if (requiredDecision != null) {
decisions.add(findDecisionById(requiredDecision.getHref()));
}
}
sortNamedElements(decisions);
}
return decisions;
}
public Collection allSubDecisions(TDRGElement element) {
Set decisions = new LinkedHashSet<>();
collectSubDecisions(element, decisions);
return decisions;
}
private void collectSubDecisions(TDRGElement element, Collection decisions) {
decisions.addAll(directSubDecisions(element));
for (TDecision child : directSubDecisions(element)) {
collectSubDecisions(child, decisions);
}
}
public List topologicalSort(TDRGElement decision) {
List decisions = new ArrayList<>();
topologicalSort((TDecision)decision, decisions);
decisions.remove(decision);
return decisions;
}
private void topologicalSort(TDecision parent, List decisions) {
if (!decisions.contains(parent)) {
for(TInformationRequirement ir: parent.getInformationRequirement()) {
TDMNElementReference requiredDecision = ir.getRequiredDecision();
if (requiredDecision != null) {
TDecision child = findDecisionById(requiredDecision.getHref());
if (child != null) {
topologicalSort(child, decisions);
}
}
}
decisions.add(parent);
}
}
public List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy