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");
}
}
}
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;
}
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;
}
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);
}
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");
}
}
}
}
}
}
Aggregations