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

com.gs.dmn.signavio.rdf2dmn.RDFModel Maven / Gradle / Ivy

There is a newer version: 8.7.3
Show newest version
/*
 * 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.signavio.rdf2dmn;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gs.dmn.feel.analysis.semantics.type.FEELTypes;
import com.gs.dmn.runtime.DMNRuntimeException;
import com.gs.dmn.signavio.rdf2dmn.json.EnumItem;
import com.gs.dmn.signavio.rdf2dmn.json.ItemDefinition;
import com.gs.dmn.signavio.rdf2dmn.json.decision.DecisionExpression;
import com.gs.dmn.signavio.rdf2dmn.json.decision.DecisionTable;
import com.gs.dmn.signavio.rdf2dmn.json.decision.OutputClause;
import com.gs.dmn.signavio.rdf2dmn.json.relation.Relation;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class RDFModel {
    public static final String INPUT_DATA = "InputData";
    public static final String DECISION = "Decision";
    public static final String INFORMATION_REQUIREMENT = "InformationRequirement";

    private static final String ORYX_NS = "http://oryx-editor.org/";
    private static final String RAZEL_NS = "http://raziel.org/";

    public static final ObjectMapper MAPPER = new ObjectMapper();

    static {
        MAPPER.setVisibility(MAPPER.getSerializationConfig().getDefaultVisibilityChecker()
                .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
    }

    private final Document model;

    public RDFModel(Document model) {
        this.model = model;
    }

    public String getAboutAttribute(Element resource) {
        return resource.getAttribute("rdf:about").replace("#", "");
    }

    public String getResourceAttribute(Element resource) {
        return resource.getAttribute("rdf:resource").replace("#", "");
    }

    public String getName(Element resource) {
        return getObject(resource, "name");
    }

    public String getLabel(Element resource) {
        return getObject(resource, "name");
    }

    public String getEnumItems(Element resource) {
        return getObject(resource, "enumitems");
    }

    public String getDecision(Element resource) {
        return getObject(resource, "decision");
    }

    public String getRelations(Element resource) {
        return getObject(resource, "relations");
    }

    public List getRelationList(String relationsString) {
        try {
            return MAPPER.readValue(relationsString, MAPPER.getTypeFactory().constructCollectionType(List.class, Relation.class));
        } catch (IOException e) {
            throw new DMNRuntimeException(String.format("Cannot deserialize relations '%s'", relationsString), e);
        }
    }

    public List getEnumItemList(String enumItemsString) {
        try {
            return MAPPER.readValue(enumItemsString, MAPPER.getTypeFactory().constructCollectionType(List.class, EnumItem.class));
        } catch (IOException e) {
            throw new DMNRuntimeException(String.format("Cannot deserialize enumItems '%s'", enumItemsString), e);
        }
    }

    public String getObject(Element resource, String propertyName) {
        NodeList elementsByTagName = resource.getElementsByTagName(propertyName);
        for (int i = 0; i < elementsByTagName.getLength(); i++) {
            Node item = elementsByTagName.item(i);
            String textContent = item.getTextContent();
            if (!StringUtils.isBlank(textContent)) {
                return textContent;
            }
        }
        return null;
    }

    public boolean isDecision(Element resource) {
        return isElementType(resource, DECISION);
    }

    public boolean isInputData(Element resource) {
        return isElementType(resource, INPUT_DATA);
    }

    public List findAllInformationRequirement() {
        return findAll(INFORMATION_REQUIREMENT);
    }

    private List findAll(String type) {
        List result = new ArrayList<>();
        NodeList descriptions = model.getDocumentElement().getElementsByTagName("rdf:Description");
        for (int i = 0; i < descriptions.getLength(); i++) {
            Node description = descriptions.item(i);
            NodeList properties = description.getChildNodes();
            for (int j = 0; j < properties.getLength(); j++) {
                Node tag = properties.item(j);
                if (tag != null) {
                    String nodeName = tag.getNodeName();
                    if ("type".equalsIgnoreCase(nodeName)) {
                        String nodeValue = tag.getTextContent();
                        if (type.equals(nodeValue)) {
                            result.add((Element) description);
                        }
                    }
                }
            }
        }
        return result;
    }

    public List findAllDecision() {
        return findAll(DECISION);
    }

    public List findAllInputData() {
        return findAll(INPUT_DATA);
    }

    public Element findDecisionById(String shapeId) {
        List allInputData = findAllDecision();
        for(Element element: allInputData) {
            if (getAboutAttribute(element).equals(shapeId)) {
                return element;
            }
        }
        return null;
    }

    public Element findInputDataById(String shapeId) {
        List allInputData = findAllInputData();
        for(Element element: allInputData) {
            if (getAboutAttribute(element).equals(shapeId)) {
                return element;
            }
        }
        return null;
    }

    private boolean isElementType(Element resource, String type) {
        NodeList children = resource.getElementsByTagName("type");
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            String textContent = child.getTextContent();
            if (type.equals(textContent)) {
                return true;
            }
        }
        return false;
    }

    public String getFEELType(Element resource) {
        List types = getTypes(resource);
        List foundTypes = types.stream().filter(FEELTypes.FEEL_TYPE_NAMES::contains).collect(Collectors.toList());
        return foundTypes.size() == 1 ? foundTypes.get(0) : null;
    }

    private List getTypes(Element resource) {
        List types = new ArrayList<>();
        NodeList children = resource.getElementsByTagName("type");
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            String textContent = child.getTextContent();
            types.add(textContent);
        }
        return types;
    }

    public List findAllObjects(Element decision, String propertyName) {
        List nodes = new ArrayList<>();
        NodeList nodeList = decision.getElementsByTagName(propertyName);
        for (int i = 0; i < nodeList.getLength(); i++) {
            nodes.add((Element) nodeList.item(i));
        }
        return nodes;
    }

    public String pathName(Element element, String outputId) {
        try {
            if (isDecision(element)) {
                String decisionText = getDecision(element);
                DecisionExpression expression = MAPPER.readValue(decisionText, DecisionExpression.class);
                if (expression instanceof DecisionTable) {
                    for (OutputClause oc : ((DecisionTable) expression).getOutputClauses()) {
                        ItemDefinition itemDefinition = oc.getItemDefinition();
                        if (outputId.equals(oc.getId())) {
                            return itemDefinition.getName();
                        }
                    }
                }
            } else if (isInputData(element)) {
                String relationsText = getRelations(element);
                List relations = MAPPER.readValue(relationsText, new TypeReference>(){});
                for(Relation relation: relations) {
                    if (relation.getValue().getPathElements().contains(Integer.valueOf(outputId))) {
                        return relation.getValue().getName();
                    }
                }
            }
            throw new DMNRuntimeException(String.format("Cannot find output '%s' in element '%s'", outputId, element.getAttribute("id")));
        } catch (Exception e) {
            throw new DMNRuntimeException(String.format("Cannot find output '%s' in element '%s'", outputId, element.getAttribute("id")), e);
        }
    }

    boolean isList(Element resource) {
        return Boolean.parseBoolean(getObject(resource, "islist"));
    }

    public Element findDescriptionById(String resourceId) {
        if (!resourceId.startsWith("#")) {
            resourceId = "#" + resourceId;
        }
        NodeList descriptions = model.getDocumentElement().getElementsByTagName("rdf:Description");
        for (int i = 0; i < descriptions.getLength(); i++) {
            Node description = descriptions.item(i);
            Node about = description.getAttributes().getNamedItem("rdf:about");
            if (resourceId.equals(about.getNodeValue())) {
                return (Element) description;
            }
        }
        return null;
    }

    public boolean hasSingleOutput(String decisionId) {
        try {
            Element decision = findDecisionById(decisionId);
            String decisionText = getDecision(decision);
            DecisionExpression expression;
            expression = RDFModel.MAPPER.readValue(decisionText, DecisionExpression.class);
            if (expression instanceof DecisionTable) {
                List outputClauses = ((DecisionTable) expression).getOutputClauses();
                if (outputClauses.size() == 1) {
                    return true;
                }
            }
            return false;
        } catch (Exception e) {
            return false;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy