Search in sources :

Example 1 with PropertyDefinitionKV

use of org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKV in project winery by eclipse.

the class BackendUtils method deriveWPD.

/**
 * Derives Winery's Properties Definition from an existing properties definition
 *
 * @param ci     the entity type to try to modify the WPDs
 * @param errors the list to add errors to
 */
public static void deriveWPD(TEntityType ci, List<String> errors) {
    BackendUtils.LOGGER.trace("deriveWPD");
    PropertiesDefinition propertiesDefinition = ci.getPropertiesDefinition();
    QName element = propertiesDefinition.getElement();
    if (element == null) {
        BackendUtils.LOGGER.debug("only works for an element definition, not for types");
    } else {
        BackendUtils.LOGGER.debug("Looking for the definition of {" + element.getNamespaceURI() + "}" + element.getLocalPart());
        // fetch the XSD defining the element
        final XsdImportManager xsdImportManager = RepositoryFactory.getRepository().getXsdImportManager();
        Map<String, RepositoryFileReference> mapFromLocalNameToXSD = xsdImportManager.getMapFromLocalNameToXSD(new Namespace(element.getNamespaceURI(), false), false);
        RepositoryFileReference ref = mapFromLocalNameToXSD.get(element.getLocalPart());
        if (ref == null) {
            String msg = "XSD not found for " + element.getNamespaceURI() + " / " + element.getLocalPart();
            BackendUtils.LOGGER.debug(msg);
            errors.add(msg);
            return;
        }
        final Optional<XSModel> xsModelOptional = BackendUtils.getXSModel(ref);
        if (!xsModelOptional.isPresent()) {
            LOGGER.error("no XSModel found");
        }
        XSModel xsModel = xsModelOptional.get();
        XSElementDeclaration elementDeclaration = xsModel.getElementDeclaration(element.getLocalPart(), element.getNamespaceURI());
        if (elementDeclaration == null) {
            String msg = "XSD model claimed to contain declaration for {" + element.getNamespaceURI() + "}" + element.getLocalPart() + ", but it did not.";
            BackendUtils.LOGGER.debug(msg);
            errors.add(msg);
            return;
        }
        // go through the XSD definition and
        XSTypeDefinition typeDefinition = elementDeclaration.getTypeDefinition();
        if (typeDefinition instanceof XSComplexTypeDefinition) {
            XSComplexTypeDefinition cTypeDefinition = (XSComplexTypeDefinition) typeDefinition;
            XSParticle particle = cTypeDefinition.getParticle();
            if (particle == null) {
                BackendUtils.LOGGER.debug("XSD does not follow the requirements put by winery: Complex type does not contain particles");
            } else {
                XSTerm term = particle.getTerm();
                if (term instanceof XSModelGroup) {
                    XSModelGroup modelGroup = (XSModelGroup) term;
                    if (modelGroup.getCompositor() == XSModelGroup.COMPOSITOR_SEQUENCE) {
                        XSObjectList particles = modelGroup.getParticles();
                        int len = particles.getLength();
                        boolean everyThingIsASimpleType = true;
                        PropertyDefinitionKVList list = new PropertyDefinitionKVList();
                        if (len != 0) {
                            for (int i = 0; i < len; i++) {
                                XSParticle innerParticle = (XSParticle) particles.item(i);
                                XSTerm innerTerm = innerParticle.getTerm();
                                if (innerTerm instanceof XSElementDeclaration) {
                                    XSElementDeclaration innerElementDeclaration = (XSElementDeclaration) innerTerm;
                                    String name = innerElementDeclaration.getName();
                                    XSTypeDefinition innerTypeDefinition = innerElementDeclaration.getTypeDefinition();
                                    if (innerTypeDefinition instanceof XSSimpleType) {
                                        XSSimpleType xsSimpleType = (XSSimpleType) innerTypeDefinition;
                                        String typeNS = xsSimpleType.getNamespace();
                                        String typeName = xsSimpleType.getName();
                                        if (typeNS.equals(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
                                            PropertyDefinitionKV def = new PropertyDefinitionKV();
                                            def.setKey(name);
                                            // convention at WPD: use "xsd" as prefix for XML Schema Definition
                                            def.setType("xsd:" + typeName);
                                            list.add(def);
                                        } else {
                                            everyThingIsASimpleType = false;
                                            break;
                                        }
                                    } else {
                                        everyThingIsASimpleType = false;
                                        break;
                                    }
                                } else {
                                    everyThingIsASimpleType = false;
                                    break;
                                }
                            }
                        }
                        if (everyThingIsASimpleType) {
                            // everything went allright, we can add a WPD
                            WinerysPropertiesDefinition wpd = new WinerysPropertiesDefinition();
                            wpd.setIsDerivedFromXSD(Boolean.TRUE);
                            wpd.setElementName(element.getLocalPart());
                            wpd.setNamespace(element.getNamespaceURI());
                            wpd.setPropertyDefinitionKVList(list);
                            ModelUtilities.replaceWinerysPropertiesDefinition(ci, wpd);
                            BackendUtils.LOGGER.debug("Successfully generated WPD");
                        } else {
                            BackendUtils.LOGGER.debug("XSD does not follow the requirements put by winery: Not all types in the sequence are simple types");
                        }
                    } else {
                        BackendUtils.LOGGER.debug("XSD does not follow the requirements put by winery: Model group is not a sequence");
                    }
                } else {
                    BackendUtils.LOGGER.debug("XSD does not follow the requirements put by winery: Not a model group");
                }
            }
        } else {
            BackendUtils.LOGGER.debug("XSD does not follow the requirements put by winery: No Complex Type Definition");
        }
    }
}
Also used : XSTypeDefinition(org.apache.xerces.xs.XSTypeDefinition) XSObjectList(org.apache.xerces.xs.XSObjectList) PropertyDefinitionKV(org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKV) XSParticle(org.apache.xerces.xs.XSParticle) XSTerm(org.apache.xerces.xs.XSTerm) QName(javax.xml.namespace.QName) WinerysPropertiesDefinition(org.eclipse.winery.model.tosca.kvproperties.WinerysPropertiesDefinition) Namespace(org.eclipse.winery.common.ids.Namespace) HasTargetNamespace(org.eclipse.winery.model.tosca.HasTargetNamespace) XSComplexTypeDefinition(org.apache.xerces.xs.XSComplexTypeDefinition) XSSimpleType(org.apache.xerces.impl.dv.XSSimpleType) RepositoryFileReference(org.eclipse.winery.common.RepositoryFileReference) WinerysPropertiesDefinition(org.eclipse.winery.model.tosca.kvproperties.WinerysPropertiesDefinition) PropertiesDefinition(org.eclipse.winery.model.tosca.TEntityType.PropertiesDefinition) XSElementDeclaration(org.apache.xerces.xs.XSElementDeclaration) XSModel(org.apache.xerces.xs.XSModel) PropertyDefinitionKVList(org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKVList) XsdImportManager(org.eclipse.winery.repository.backend.xsd.XsdImportManager) XSModelGroup(org.apache.xerces.xs.XSModelGroup)

Example 2 with PropertyDefinitionKV

use of org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKV in project winery by eclipse.

the class ModelUtilities method getWinerysPropertiesDefinitionXsdAsDocument.

/**
 * Generates a XSD when Winery's K/V properties are used. This method is put here instead of
 * WinerysPropertiesDefinitionResource to avoid generating the subresource
 * <p>
 * public because of the usage by TOSCAEXportUtil
 *
 * @return empty Document, if Winery's Properties Definition is not fully filled (e.g., no wrapping element defined)
 */
public static Document getWinerysPropertiesDefinitionXsdAsDocument(WinerysPropertiesDefinition wpd) {
    /*
         * This is a quick hack: an XML schema container is created for each
         * element. Smarter solution: create a hash from namespace to XML schema
         * element and re-use that for each new element
         * Drawback of "smarter" solution: not a single XSD file any more
         */
    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder;
    try {
        docBuilder = docFactory.newDocumentBuilder();
    } catch (ParserConfigurationException e) {
        ModelUtilities.LOGGER.debug(e.getMessage(), e);
        throw new IllegalStateException("Could not instantiate document builder", e);
    }
    Document doc = docBuilder.newDocument();
    if (!ModelUtilities.allRequiredFieldsNonNull(wpd)) {
        // wpd not fully filled -> valid XSD cannot be provided
        // fallback: add comment and return "empty" document
        Comment comment = doc.createComment("Required fields are missing in Winery's key/value properties definition.");
        doc.appendChild(comment);
        return doc;
    }
    // create XSD schema container
    Element schemaElement = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "schema");
    doc.appendChild(schemaElement);
    schemaElement.setAttribute("elementFormDefault", "qualified");
    schemaElement.setAttribute("attributeFormDefault", "unqualified");
    schemaElement.setAttribute("targetNamespace", wpd.getNamespace());
    // create XSD element itself
    Element el = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "element");
    schemaElement.appendChild(el);
    el.setAttribute("name", wpd.getElementName());
    Element el2 = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "complexType");
    el.appendChild(el2);
    el = el2;
    el2 = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "sequence");
    el.appendChild(el2);
    el = el2;
    // currently, "xsd" is a hardcoded prefix in the type definition
    el.setAttribute("xmlns:xsd", XMLConstants.W3C_XML_SCHEMA_NS_URI);
    for (PropertyDefinitionKV prop : wpd.getPropertyDefinitionKVList()) {
        el2 = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "element");
        el.appendChild(el2);
        el2.setAttribute("name", prop.getKey());
        // prop.getType has the prefix included
        el2.setAttribute("type", prop.getType());
    }
    return doc;
}
Also used : Comment(org.w3c.dom.Comment) DocumentBuilderFactory(javax.xml.parsers.DocumentBuilderFactory) PropertyDefinitionKV(org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKV) DocumentBuilder(javax.xml.parsers.DocumentBuilder) Element(org.w3c.dom.Element) SourceOrTargetElement(org.eclipse.winery.model.tosca.TRelationshipTemplate.SourceOrTargetElement) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) Document(org.w3c.dom.Document)

Example 3 with PropertyDefinitionKV

use of org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKV in project winery by eclipse.

the class ModelUtilities method allRequiredFieldsNonNull.

public static boolean allRequiredFieldsNonNull(WinerysPropertiesDefinition wpd) {
    boolean valid = wpd.getNamespace() != null;
    valid = valid && (wpd.getElementName() != null);
    if (valid) {
        PropertyDefinitionKVList propertyDefinitionKVList = wpd.getPropertyDefinitionKVList();
        valid = (propertyDefinitionKVList != null);
        if (valid) {
            for (PropertyDefinitionKV def : propertyDefinitionKVList) {
                valid = valid && (def.getKey() != null);
                valid = valid && (def.getType() != null);
            }
        }
    }
    return valid;
}
Also used : PropertyDefinitionKV(org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKV) PropertyDefinitionKVList(org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKVList)

Example 4 with PropertyDefinitionKV

use of org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKV in project winery by eclipse.

the class BackendUtils method initializeProperties.

/**
 * Properties need to be initialized in the case of K/V Properties
 *
 * @param repository     The repository to work on
 * @param entityTemplate the entity template to update
 */
public static void initializeProperties(IRepository repository, TEntityTemplate entityTemplate) {
    Objects.requireNonNull(repository);
    Objects.requireNonNull(entityTemplate);
    Objects.requireNonNull(entityTemplate.getType());
    final TEntityType entityType = repository.getTypeForTemplate(entityTemplate);
    final WinerysPropertiesDefinition winerysPropertiesDefinition = entityType.getWinerysPropertiesDefinition();
    if (winerysPropertiesDefinition == null) {
        return;
    }
    Document document;
    try {
        document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
    } catch (ParserConfigurationException e) {
        LOGGER.error("Could not create document", e);
        return;
    }
    final String namespace = winerysPropertiesDefinition.getNamespace();
    final Element wrapperElement = document.createElementNS(namespace, winerysPropertiesDefinition.getElementName());
    document.appendChild(wrapperElement);
    // we produce the serialization in the same order the XSD would be generated (because of the usage of xsd:sequence)
    for (PropertyDefinitionKV propertyDefinitionKV : winerysPropertiesDefinition.getPropertyDefinitionKVList()) {
        // we always write the element tag as the XSD forces that
        final Element valueElement = document.createElementNS(namespace, propertyDefinitionKV.getKey());
        wrapperElement.appendChild(valueElement);
    }
    TEntityTemplate.Properties properties = new TEntityTemplate.Properties();
    properties.setAny(document.getDocumentElement());
    entityTemplate.setProperties(properties);
}
Also used : PropertyDefinitionKV(org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKV) TEntityTemplate(org.eclipse.winery.model.tosca.TEntityTemplate) TEntityType(org.eclipse.winery.model.tosca.TEntityType) JAXBElement(javax.xml.bind.JAXBElement) Element(org.w3c.dom.Element) WinerysPropertiesDefinition(org.eclipse.winery.model.tosca.kvproperties.WinerysPropertiesDefinition) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) Document(org.w3c.dom.Document)

Example 5 with PropertyDefinitionKV

use of org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKV in project winery by eclipse.

the class ConsistencyChecker method checkServiceTemplate.

public static void checkServiceTemplate(ConsistencyErrorLogger errorLogger, ConsistencyCheckerConfiguration configuration, ServiceTemplateId id) {
    final TServiceTemplate serviceTemplate = configuration.getRepository().getElement(id);
    if (serviceTemplate.getTopologyTemplate() == null) {
        return;
    }
    @NonNull final List<TNodeTemplate> nodeTemplates = serviceTemplate.getTopologyTemplate().getNodeTemplates();
    for (TNodeTemplate nodeTemplate : nodeTemplates) {
        final TNodeType nodeType = configuration.getRepository().getElement(new NodeTypeId(nodeTemplate.getType()));
        final WinerysPropertiesDefinition winerysPropertiesDefinition = nodeType.getWinerysPropertiesDefinition();
        if (winerysPropertiesDefinition != null) {
            PropertyDefinitionKVList list = winerysPropertiesDefinition.getPropertyDefinitionKVList();
            if (list != null) {
                // iterate on all defined properties
                for (PropertyDefinitionKV propdef : list) {
                    String key = propdef.getKey();
                    if (key == null) {
                        printAndAddError(errorLogger, configuration.getVerbosity(), id, "key is null");
                        continue;
                    }
                    // assign value, but change "null" to "" if no property is defined
                    final Map<String, String> propertiesKV = ModelUtilities.getPropertiesKV(nodeTemplate);
                    if (propertiesKV == null) {
                        printAndAddError(errorLogger, configuration.getVerbosity(), id, "propertiesKV of node template " + nodeTemplate.getId() + " is null");
                    }
                }
            }
        }
    }
}
Also used : PropertyDefinitionKV(org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKV) NonNull(org.eclipse.jgit.annotations.NonNull) WinerysPropertiesDefinition(org.eclipse.winery.model.tosca.kvproperties.WinerysPropertiesDefinition) PropertyDefinitionKVList(org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKVList)

Aggregations

PropertyDefinitionKV (org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKV)6 WinerysPropertiesDefinition (org.eclipse.winery.model.tosca.kvproperties.WinerysPropertiesDefinition)4 PropertyDefinitionKVList (org.eclipse.winery.model.tosca.kvproperties.PropertyDefinitionKVList)3 QName (javax.xml.namespace.QName)2 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)2 RepositoryFileReference (org.eclipse.winery.common.RepositoryFileReference)2 Namespace (org.eclipse.winery.common.ids.Namespace)2 Document (org.w3c.dom.Document)2 Element (org.w3c.dom.Element)2 JAXBElement (javax.xml.bind.JAXBElement)1 DocumentBuilder (javax.xml.parsers.DocumentBuilder)1 DocumentBuilderFactory (javax.xml.parsers.DocumentBuilderFactory)1 XSSimpleType (org.apache.xerces.impl.dv.XSSimpleType)1 XSComplexTypeDefinition (org.apache.xerces.xs.XSComplexTypeDefinition)1 XSElementDeclaration (org.apache.xerces.xs.XSElementDeclaration)1 XSModel (org.apache.xerces.xs.XSModel)1 XSModelGroup (org.apache.xerces.xs.XSModelGroup)1 XSObjectList (org.apache.xerces.xs.XSObjectList)1 XSParticle (org.apache.xerces.xs.XSParticle)1 XSTerm (org.apache.xerces.xs.XSTerm)1