use of org.eclipse.winery.model.tosca.TEntityType.PropertiesDefinition 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.TEntityType.PropertiesDefinition 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.TEntityType.PropertiesDefinition in project winery by eclipse.
the class PropertiesDefinitionResource method onJsonPost.
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response onJsonPost(PropertiesDefinitionResourceApiData data) {
if (data.selectedValue == PropertiesDefinitionEnum.Element || data.selectedValue == PropertiesDefinitionEnum.Type) {
// first of all, remove Winery's Properties definition (if it exists)
ModelUtilities.removeWinerysPropertiesDefinition(this.getEntityType());
// replace old properties definition by new one
PropertiesDefinition def = new PropertiesDefinition();
if (data.propertiesDefinition.getElement() != null) {
def.setElement(data.propertiesDefinition.getElement());
} else if (data.propertiesDefinition.getType() != null) {
def.setType(data.propertiesDefinition.getType());
} else {
return Response.status(Status.BAD_REQUEST).entity("Wrong data submitted!").build();
}
this.getEntityType().setPropertiesDefinition(def);
List<String> errors = new ArrayList<>();
BackendUtils.deriveWPD(this.getEntityType(), errors);
// currently the errors are just logged
for (String error : errors) {
PropertiesDefinitionResource.LOGGER.debug(error);
}
return RestUtils.persist(this.parentRes);
} else if (data.selectedValue == PropertiesDefinitionEnum.Custom) {
TEntityType et = this.parentRes.getEntityType();
// clear current properties definition
et.setPropertiesDefinition(null);
// create winery properties definition and persist it
ModelUtilities.replaceWinerysPropertiesDefinition(et, data.winerysPropertiesDefinition);
String namespace = data.winerysPropertiesDefinition.getNamespace();
NamespaceManager namespaceManager = RepositoryFactory.getRepository().getNamespaceManager();
if (!namespaceManager.hasPrefix(namespace)) {
namespaceManager.addNamespace(namespace);
}
return RestUtils.persist(this.parentRes);
}
return Response.status(Status.BAD_REQUEST).entity("Wrong data submitted!").build();
}
use of org.eclipse.winery.model.tosca.TEntityType.PropertiesDefinition 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