| /******************************************************************************* |
| * Copyright (C) 2021 the Eclipse BaSyx Authors |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| ******************************************************************************/ |
| package org.eclipse.basyx.submodel.factory.xml.converters.qualifier.qualifiable; |
| |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.basyx.submodel.factory.xml.XMLHelper; |
| import org.eclipse.basyx.submodel.factory.xml.converters.qualifier.HasSemanticsXMLConverter; |
| import org.eclipse.basyx.submodel.factory.xml.converters.reference.ReferenceXMLConverter; |
| import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IConstraint; |
| import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IFormula; |
| import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifiable; |
| import org.eclipse.basyx.submodel.metamodel.api.qualifier.qualifiable.IQualifier; |
| import org.eclipse.basyx.submodel.metamodel.api.reference.IReference; |
| import org.eclipse.basyx.submodel.metamodel.map.qualifier.HasSemantics; |
| import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Formula; |
| import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifiable; |
| import org.eclipse.basyx.submodel.metamodel.map.qualifier.qualifiable.Qualifier; |
| import org.eclipse.basyx.submodel.metamodel.map.reference.Reference; |
| import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.property.valuetypedef.PropertyValueTypeDefHelper; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| |
| /** |
| * Handles the conversion between an IQualifiable object and the XML tag <aas:qualifier> in both directions |
| * |
| * @author conradi |
| * |
| */ |
| public class QualifiableXMLConverter { |
| |
| private static Logger logger = LoggerFactory.getLogger(QualifiableXMLConverter.class); |
| |
| public static final String QUALIFIER = "aas:qualifier"; |
| public static final String FORMULA = "aas:formula"; |
| public static final String DEPENDS_ON_REFS = "aas:dependsOnRefs"; |
| public static final String REFERENCE = "aas:reference"; |
| public static final String TYPE = "aas:type"; |
| public static final String VALUE = "aas:value"; |
| public static final String VALUE_TYPE = "aas:valueType"; |
| public static final String VALUE_ID = "aas:valueId"; |
| |
| |
| /** |
| * Populates a given Qualifiable object with the data form the given XML |
| * |
| * @param xmlObject the XML map containing the <aas:qualifier> tag |
| * @param qualifiable the Qualifiable object to be populated |
| */ |
| @SuppressWarnings("unchecked") |
| public static void populateQualifiable(Map<String, Object> xmlObject, Qualifiable qualifiable) { |
| Map<String, Object> qualifierObj = (Map<String, Object>) xmlObject.get(QUALIFIER); |
| if (qualifierObj != null) { |
| qualifiable.setQualifiers(parseConstraints(qualifierObj)); |
| } |
| } |
| |
| |
| /** |
| * Parses the IConstraint objects form XML |
| * |
| * @param xmlConstraints the XML map containing the <aas:formula> and <aas:qualifier> tags |
| * @return the Set of IConstraint objects parsed |
| */ |
| private static Collection<IConstraint> parseConstraints(Map<String, Object> xmlConstraints) { |
| Collection<IConstraint> constraints = new HashSet<>(); |
| |
| if(xmlConstraints == null) return constraints; |
| |
| List<Map<String, Object>> xmlQualifier = XMLHelper.getList(xmlConstraints.get(QUALIFIER)); |
| xmlQualifier.stream().map(QualifiableXMLConverter::parseQualifier).forEach(constraints::add); |
| |
| |
| List<Map<String, Object>> xmlFormula = XMLHelper.getList(xmlConstraints.get(FORMULA)); |
| xmlFormula.stream().map(QualifiableXMLConverter::parseFormula).forEach(constraints::add); |
| |
| |
| return constraints; |
| } |
| |
| |
| /** |
| * Parses a Formula object form XML |
| * |
| * @param xmlFormula the XML map containing the content of the <aas:formula> tag |
| * @return the parsed Formula object |
| */ |
| @SuppressWarnings("unchecked") |
| private static Formula parseFormula(Map<String, Object> xmlFormula) { |
| Map<String, Object> dependsOnObj = (Map<String, Object>) xmlFormula.get(DEPENDS_ON_REFS); |
| Collection<IReference> referenceList = new HashSet<>(); |
| |
| List<Map<String, Object>> xmlReferenceList = XMLHelper.getList(dependsOnObj.get(REFERENCE)); |
| for (Map<String, Object> xmlReference : xmlReferenceList) { |
| referenceList.add(ReferenceXMLConverter.parseReference(xmlReference)); |
| } |
| |
| return new Formula(referenceList); |
| } |
| |
| |
| /** |
| * Parses a Qualifier object form XML |
| * |
| * @param xmlQualifier the XML map containing the content of the <aas:qualifier> tag |
| * @return the parsed Qualifier object |
| */ |
| @SuppressWarnings("unchecked") |
| private static Qualifier parseQualifier(Map<String, Object> xmlQualifier) { |
| String type = XMLHelper.getString(xmlQualifier.get(TYPE)); |
| String value = XMLHelper.getString(xmlQualifier.get(VALUE)); |
| String valueType = XMLHelper.getString(xmlQualifier.get(VALUE_TYPE)); |
| Map<String, Object> qualifierValueIdObj = (Map<String, Object>) xmlQualifier.get(VALUE_ID); |
| |
| Reference ref = ReferenceXMLConverter.parseReference(qualifierValueIdObj); |
| |
| Qualifier qualifier = new Qualifier(); |
| HasSemanticsXMLConverter.populateHasSemantics(xmlQualifier, HasSemantics.createAsFacade(qualifier)); |
| |
| qualifier.setType(type); |
| qualifier.setValue(value); |
| qualifier.setValueId(ref); |
| |
| if (valueType == null || valueType.isEmpty()) { |
| logger.warn("Creating element " + xmlQualifier + " without mandatory valueType!"); |
| } else { |
| qualifier.setValueType(PropertyValueTypeDefHelper.fromName(valueType)); |
| } |
| return qualifier; |
| } |
| |
| |
| |
| |
| /** |
| * Populates a given XML map with the data from a given IQualifiable object<br> |
| * Creates the <aas:qualifier> tag in the given root |
| * |
| * @param document the XML document |
| * @param root the XML root Element to be populated |
| * @param qualifiable the IQualifiable object to be converted to XML |
| */ |
| public static void populateQualifiableXML(Document document, Element root, IQualifiable qualifiable) { |
| if(qualifiable.getQualifiers() == null || qualifiable.getQualifiers().size() == 0) return; |
| |
| |
| Collection<IConstraint> constraints = qualifiable.getQualifiers(); |
| |
| Element qualifierRoot = document.createElement(QUALIFIER); |
| |
| for (IConstraint constraint : constraints) { |
| qualifierRoot.appendChild(buildQualifiersXML(document, constraint)); |
| } |
| |
| root.appendChild(qualifierRoot); |
| } |
| |
| |
| /** |
| * Builds XML from a given IConstraint objcet |
| * |
| * @param document |
| * the XML document |
| * @param constraint |
| * the IConstraint to be converted to XML |
| * @return the <aas:qualifier> XML tag build from the IConstraint |
| */ |
| private static Element buildQualifiersXML(Document document, IConstraint constraint) { |
| |
| //the constraints can be IFormula or IQualifier |
| if(constraint instanceof IFormula) { |
| return buildFormulaXML(document, (IFormula) constraint); |
| } else if(constraint instanceof IQualifier) { |
| return buildQualifierXML(document, (IQualifier) constraint); |
| } |
| |
| throw new RuntimeException("Unknown qualifier type " + constraint); |
| } |
| |
| |
| /** |
| * Builds XML from a given IFormula object |
| * |
| * @param document the XML document |
| * @param formula the IFormula to be converted to XML |
| * @return the <aas:formula> XML tag build from the IFormula |
| */ |
| private static Element buildFormulaXML(Document document, IFormula formula) { |
| Element formulaRoot = document.createElement(FORMULA); |
| Element dependsOnRoot = document.createElement(DEPENDS_ON_REFS); |
| Collection<IReference> ref = formula.getDependsOn(); |
| Element refrenceRoot = document.createElement(REFERENCE); |
| refrenceRoot.appendChild(ReferenceXMLConverter.buildReferencesXML(document, ref)); |
| dependsOnRoot.appendChild(refrenceRoot); |
| formulaRoot.appendChild(dependsOnRoot); |
| return formulaRoot; |
| } |
| |
| |
| /** |
| * Builds XML from a given IQualifier object |
| * |
| * @param document the XML document |
| * @param qualifier the IQualifier to be converted to XML |
| * @return the <aas:qualifier> XML tag build from the IQualifier |
| */ |
| private static Element buildQualifierXML(Document document, IQualifier qualifier) { |
| IReference qualId = qualifier.getValueId(); |
| String type = XMLHelper.getString(qualifier.getType()); |
| String value = XMLHelper.getString(qualifier.getValue()); |
| String valueType = qualifier.getValueType().toString(); |
| Element qualifierRoot = document.createElement(QUALIFIER); |
| |
| Element qualifierValueId = document.createElement(VALUE_ID); |
| Element keysElement = ReferenceXMLConverter.buildReferenceXML(document, qualId); |
| if(keysElement != null) { |
| qualifierValueId.appendChild(keysElement); |
| } |
| qualifierRoot.appendChild(qualifierValueId); |
| |
| Element qualifierValue = document.createElement(VALUE); |
| qualifierValue.appendChild(document.createTextNode(value)); |
| qualifierRoot.appendChild(qualifierValue); |
| |
| Element qualifierType = document.createElement(TYPE); |
| qualifierType.appendChild(document.createTextNode(type)); |
| qualifierRoot.appendChild(qualifierType); |
| |
| Element qualifierValueType = document.createElement(VALUE_TYPE); |
| qualifierValueType.appendChild(document.createTextNode(valueType)); |
| qualifierRoot.appendChild(qualifierValueType); |
| |
| HasSemanticsXMLConverter.populateHasSemanticsXML(document, qualifierRoot, qualifier); |
| |
| return qualifierRoot; |
| } |
| } |