use of org.eclipse.winery.model.tosca.kvproperties.WinerysPropertiesDefinition 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.WinerysPropertiesDefinition in project winery by eclipse.
the class CsarImporter method adjustEntityType.
/**
* All EntityTypes may contain properties definition. In case a winery properties definition is found, the TOSCA
* conforming properties definition is removed
*
* @param ci the entity type
* @param wid the Winery id of the entitytype
* @param newDefs the definitions, the entiy type is contained in. The imports might be adjusted here
* @param errors Used to collect the errors
*/
private static void adjustEntityType(TEntityType ci, EntityTypeId wid, Definitions newDefs, final List<String> errors) {
PropertiesDefinition propertiesDefinition = ci.getPropertiesDefinition();
if (propertiesDefinition != null) {
WinerysPropertiesDefinition winerysPropertiesDefinition = ModelUtilities.getWinerysPropertiesDefinition(ci);
boolean deriveWPD;
if (winerysPropertiesDefinition == null) {
deriveWPD = true;
} else {
if (winerysPropertiesDefinition.getIsDerivedFromXSD() == null) {
// if the winery's properties are defined by Winery itself,
// remove the TOSCA conforming properties definition as a Winery properties definition exists (and which takes precedence)
ci.setPropertiesDefinition(null);
// no derivation from properties required as the properties are generated by Winery
deriveWPD = false;
// we have to remove the import, too
// Determine the location
String elementName = winerysPropertiesDefinition.getElementName();
String loc = BackendUtils.getImportLocationForWinerysPropertiesDefinitionXSD(wid, null, elementName);
// remove the import matching that location
List<TImport> imports = newDefs.getImport();
boolean found = false;
if (imports != null) {
Iterator<TImport> iterator = imports.iterator();
TImport imp;
while (iterator.hasNext()) {
imp = iterator.next();
// TODO: add check for QNames.QNAME_WINERYS_PROPERTIES_DEFINITION_ATTRIBUTE instead of import location. The current routine, however, works, too.
if (imp.getLocation().equals(loc)) {
found = true;
break;
}
}
// noinspection StatementWithEmptyBody
if (found) {
// imp with Winery's k/v location found
iterator.remove();
// the XSD has been imported in importOtherImport
// it was too difficult to do the location check there, therefore we just remove the XSD from the repository here
XSDImportId importId = new XSDImportId(winerysPropertiesDefinition.getNamespace(), elementName, false);
try {
RepositoryFactory.getRepository().forceDelete(importId);
} catch (IOException e) {
CsarImporter.LOGGER.debug("Could not delete Winery's generated XSD definition", e);
errors.add("Could not delete Winery's generated XSD definition");
}
} else {
// K/V properties definition was incomplete
}
}
} else {
// winery's properties are derived from an XSD
// The export does NOT add an imports statement: only the wpd exists
// We remove that as
ModelUtilities.removeWinerysPropertiesDefinition(ci);
// derive the WPDs again from the properties definition
deriveWPD = true;
}
}
if (deriveWPD) {
BackendUtils.deriveWPD(ci, errors);
}
}
}
use of org.eclipse.winery.model.tosca.kvproperties.WinerysPropertiesDefinition 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");
}
}
}
}
}
}
use of org.eclipse.winery.model.tosca.kvproperties.WinerysPropertiesDefinition in project winery by eclipse.
the class ConsistencyChecker method checkPropertiesValidation.
public static void checkPropertiesValidation(ConsistencyErrorLogger errorLogger, ConsistencyCheckerConfiguration configuration, DefinitionsChildId id) {
if (id instanceof EntityTemplateId) {
TEntityTemplate entityTemplate = (TEntityTemplate) configuration.getRepository().getDefinitions(id).getElement();
if (Objects.isNull(entityTemplate.getType())) {
// no printing necessary; type consistency is checked at other places
return;
}
final TEntityType entityType = configuration.getRepository().getTypeForTemplate(entityTemplate);
final WinerysPropertiesDefinition winerysPropertiesDefinition = entityType.getWinerysPropertiesDefinition();
final TEntityType.PropertiesDefinition propertiesDefinition = entityType.getPropertiesDefinition();
if ((winerysPropertiesDefinition != null) || (propertiesDefinition != null)) {
final TEntityTemplate.Properties properties = entityTemplate.getProperties();
if (properties == null) {
printAndAddError(errorLogger, configuration.getVerbosity(), id, "Properties required, but no properties defined");
return;
}
if (winerysPropertiesDefinition != null) {
Map<String, String> kvProperties = entityTemplate.getProperties().getKVProperties();
if (kvProperties.isEmpty()) {
printAndAddError(errorLogger, configuration.getVerbosity(), id, "Properties required, but no properties set (any case)");
return;
}
for (PropertyDefinitionKV propertyDefinitionKV : winerysPropertiesDefinition.getPropertyDefinitionKVList().getPropertyDefinitionKVs()) {
String key = propertyDefinitionKV.getKey();
if (kvProperties.get(key) == null) {
printAndAddError(errorLogger, configuration.getVerbosity(), id, "Property " + key + " required, but not set.");
} else {
// remove the key from the map to enable checking below whether a property is defined which not requried by the property definition
kvProperties.remove(key);
}
}
// If any key is left, this is a key not defined at the schema
for (Object o : kvProperties.keySet()) {
printAndAddError(errorLogger, configuration.getVerbosity(), id, "Property " + o + " set, but not defined at schema.");
}
} else if (propertiesDefinition != null) {
@Nullable final Object any = properties.getAny();
if (any == null) {
printAndAddError(errorLogger, configuration.getVerbosity(), id, "Properties required, but no properties defined (any case)");
return;
}
@Nullable final QName element = propertiesDefinition.getElement();
if (element != null) {
final Map<String, RepositoryFileReference> mapFromLocalNameToXSD = configuration.getRepository().getXsdImportManager().getMapFromLocalNameToXSD(new Namespace(element.getNamespaceURI(), false), false);
final RepositoryFileReference repositoryFileReference = mapFromLocalNameToXSD.get(element.getLocalPart());
if (repositoryFileReference == null) {
printAndAddError(errorLogger, configuration.getVerbosity(), id, "No Xml Schema definition found for " + element);
return;
}
validate(errorLogger, repositoryFileReference, any, configuration, id);
}
}
}
}
}
use of org.eclipse.winery.model.tosca.kvproperties.WinerysPropertiesDefinition in project winery by eclipse.
the class ToscaExportUtil method writeDefinitionsElement.
/**
* Writes the Definitions belonging to the given definitgion children to the output stream
*
* @return a collection of DefinitionsChildIds referenced by the given component
* @throws RepositoryCorruptException if tcId does not exist
*/
private Collection<DefinitionsChildId> writeDefinitionsElement(IRepository repository, DefinitionsChildId tcId, OutputStream out) throws JAXBException, RepositoryCorruptException, IOException {
if (!repository.exists(tcId)) {
String error = "Component instance " + tcId.toReadableString() + " does not exist.";
ToscaExportUtil.LOGGER.error(error);
throw new RepositoryCorruptException(error);
}
this.getPrepareForExport(repository, tcId);
Definitions entryDefinitions = repository.getDefinitions(tcId);
// BEGIN: Definitions modification
// the "imports" collection contains the imports of Definitions, not of other definitions
// the other definitions are stored in entryDefinitions.getImport()
// we modify the internal definitions object directly. It is not written back to the storage. Therefore, we do not need to clone it
// the imports (pointing to not-definitions (xsd, wsdl, ...)) already have a correct relative URL. (quick hack)
URI uri = (URI) this.exportConfiguration.get(ToscaExportUtil.ExportProperties.REPOSITORY_URI.toString());
if (uri != null) {
// we are in the plain-XML mode, the URLs of the imports have to be adjusted
for (TImport i : entryDefinitions.getImport()) {
String loc = i.getLocation();
if (!loc.startsWith("../")) {
LOGGER.warn("Location is not relative for id " + tcId.toReadableString());
}
;
loc = loc.substring(3);
loc = uri + loc;
// now the location is an absolute URL
i.setLocation(loc);
}
}
// files of imports have to be added to the CSAR, too
for (TImport i : entryDefinitions.getImport()) {
String loc = i.getLocation();
if (Util.isRelativeURI(loc)) {
// locally stored, add to CSAR
GenericImportId iid = new GenericImportId(i);
String fileName = Util.getLastURIPart(loc);
fileName = Util.URLdecode(fileName);
RepositoryFileReference ref = new RepositoryFileReference(iid, fileName);
this.putRefAsReferencedItemInCsar(ref);
}
}
Collection<DefinitionsChildId> referencedDefinitionsChildIds = repository.getReferencedDefinitionsChildIds(tcId);
// adjust imports: add imports of definitions to it
Collection<TImport> imports = new ArrayList<>();
for (DefinitionsChildId id : referencedDefinitionsChildIds) {
this.addToImports(repository, id, imports);
}
entryDefinitions.getImport().addAll(imports);
if (entryDefinitions.getElement() instanceof TEntityType) {
TEntityType entityType = (TEntityType) entryDefinitions.getElement();
// we have an entity type with a possible properties definition
WinerysPropertiesDefinition wpd = entityType.getWinerysPropertiesDefinition();
if (wpd != null) {
if (wpd.getIsDerivedFromXSD() == null) {
// Write WPD only to file if it exists and is NOT derived from an XSD (which may happen during import)
String wrapperElementNamespace = wpd.getNamespace();
String wrapperElementLocalName = wpd.getElementName();
// BEGIN: add import and put into CSAR
TImport imp = new TImport();
entryDefinitions.getImport().add(imp);
// fill known import values
imp.setImportType(XMLConstants.W3C_XML_SCHEMA_NS_URI);
imp.setNamespace(wrapperElementNamespace);
// add "winerysPropertiesDefinition" flag to import tag to support
Map<QName, String> otherAttributes = imp.getOtherAttributes();
otherAttributes.put(QNames.QNAME_WINERYS_PROPERTIES_DEFINITION_ATTRIBUTE, "true");
// Determine location
String loc = BackendUtils.getImportLocationForWinerysPropertiesDefinitionXSD((EntityTypeId) tcId, uri, wrapperElementLocalName);
if (uri == null) {
ToscaExportUtil.LOGGER.trace("CSAR Export mode. Putting XSD into CSAR");
// CSAR Export mode
// XSD has to be put into the CSAR
Document document = ModelUtilities.getWinerysPropertiesDefinitionXsdAsDocument(wpd);
// loc in import is URLencoded, loc on filesystem isn't
String locInCSAR = Util.URLdecode(loc);
// furthermore, the path has to start from the root of the CSAR; currently, it starts from Definitions/
locInCSAR = locInCSAR.substring(3);
ToscaExportUtil.LOGGER.trace("Location in CSAR: {}", locInCSAR);
this.referencesToPathInCSARMap.put(new DummyRepositoryFileReferenceForGeneratedXSD(document), locInCSAR);
}
imp.setLocation(loc);
// END: add import and put into CSAR
// BEGIN: generate TOSCA conforming PropertiesDefinition
PropertiesDefinition propertiesDefinition = new PropertiesDefinition();
propertiesDefinition.setType(new QName(wrapperElementNamespace, wrapperElementLocalName));
entityType.setPropertiesDefinition(propertiesDefinition);
// END: generate TOSCA conforming PropertiesDefinition
} else {
// noinspection StatementWithEmptyBody
// otherwise WPD exists, but is derived from XSD
// we DO NOT have to remove the winery properties definition from the output to allow "debugging" of the CSAR
}
}
}
// END: Definitions modification
this.writeDefinitionsElement(entryDefinitions, out);
return referencedDefinitionsChildIds;
}
Aggregations