use of org.eclipse.winery.model.tosca.TImport in project winery by eclipse.
the class YamlCsarImporter method importImports.
/**
* @param basePath the base path where to resolve files from. This is the directory of the Definitions
* @param imports the list of imports to import. SIDE EFFECT: this list is modified. After this method has run, the
* list contains the imports to be put into the wrapper element
* @param options the set of options applicable while importing a CSAR
*/
private void importImports(Path basePath, TOSCAMetaFile tmf, List<TImport> imports, final List<String> errors, CsarImportOptions options) throws IOException {
for (TImport imp : imports) {
if (handledImports.contains(imp)) {
continue;
}
handledImports.add(imp);
String importType = imp.getImportType();
String location = imp.getLocation();
if (Namespaces.TOSCA_YAML_NS.equals(importType)) {
Path defsPath = basePath.resolve(location);
// fallback for older CSARs, where the location is given from the root
if (Files.exists(defsPath)) {
this.importDefinitions(tmf, defsPath, errors, options);
// imports of definitions don't have to be kept as these are managed by Winery
}
}
}
}
use of org.eclipse.winery.model.tosca.TImport 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 entity type is contained in. The imports might be adjusted here
* @param errors Used to collect the errors
*/
private void adjustEntityType(TEntityType ci, EntityTypeId wid, TDefinitions newDefs, final List<String> errors) {
TEntityType.PropertiesDefinition propertiesDefinition = ci.getProperties();
if (propertiesDefinition != null) {
WinerysPropertiesDefinition winerysPropertiesDefinition = ci.getWinerysPropertiesDefinition();
boolean deriveWPD;
if (winerysPropertiesDefinition == null) {
deriveWPD = true;
} else {
if (winerysPropertiesDefinition.getIsDerivedFromXSD() == 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 {
this.targetRepository.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, targetRepository);
}
}
}
use of org.eclipse.winery.model.tosca.TImport in project winery by eclipse.
the class ToscaExportUtil method specifyImports.
private TDefinitions specifyImports(IRepository repository, DefinitionsChildId tcId, Collection<DefinitionsChildId> referencedDefinitionsChildIds) {
TDefinitions 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(CsarExportConfiguration.REPOSITORY_URI.name());
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 = IdUtil.getLastURIPart(loc);
fileName = EncodingUtil.URLdecode(fileName);
RepositoryFileReference ref = new RepositoryFileReference(iid, fileName);
putRefAsReferencedItemInCsar(repository, ref);
}
}
Set<DefinitionsChildId> collect = referencedDefinitionsChildIds.stream().filter(id -> id instanceof NodeTypeImplementationId).collect(Collectors.toSet());
if (collect.stream().anyMatch(DefinitionsChildId::isSelfContained)) {
if (this.exportConfiguration.containsKey(CsarExportConfiguration.INCLUDE_DEPENDENCIES.name())) {
referencedDefinitionsChildIds.removeAll(collect.stream().filter(id -> !id.isSelfContained()).collect(Collectors.toList()));
} else if (collect.size() > 1 && collect.stream().anyMatch(id -> !id.isSelfContained())) {
referencedDefinitionsChildIds.removeAll(collect.stream().filter(DefinitionsChildId::isSelfContained).collect(Collectors.toList()));
}
}
// 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);
// END: Definitions modification
return entryDefinitions;
}
use of org.eclipse.winery.model.tosca.TImport in project winery by eclipse.
the class ToscaExportUtil method addToImports.
/**
* Adds the given id as import to the given imports collection
*/
protected void addToImports(IRepository repository, DefinitionsChildId id, Collection<TImport> imports) {
TImport imp = new TImport();
imp.setImportType(Namespaces.TOSCA_NAMESPACE);
imp.setNamespace(id.getNamespace().getDecoded());
URI uri = (URI) this.exportConfiguration.get(CsarExportConfiguration.REPOSITORY_URI.name());
if (uri == null) {
// self-contained mode
// all Definitions are contained in "Definitions" directory, therefore, we provide the filename only
// references are resolved relatively from a definitions element (COS01, line 425)
String fn = CsarExporter.getDefinitionsFileName(repository, id);
fn = EncodingUtil.URLencode(fn);
imp.setLocation(fn);
} else {
String path = Util.getUrlPath(id);
path = path + "?definitions";
URI absoluteURI = uri.resolve(path);
imp.setLocation(absoluteURI.toString());
}
imports.add(imp);
// FIXME: Currently the depended elements (such as the artifact templates linked to a node type implementation) are gathered by the corresponding "addXY" method.
// Reason: the corresponding TDefinitions element is *not* updated if a related element is added/removed.
// That means: The imports are not changed.
// The current issue is that TOSCA allows imports of Definitions only and the repository has the concrete elements as main structure
// Although during save the import can be updated (by fetching the associated resource and get the definitions of it),
// The concrete definitions cannot be determined without
// a) having a complete index of all definitions in the repository
// b) crawling through the *complete* repository
// Possibly the current solution, just lazily adding all dependent elements is the better solution.
}
use of org.eclipse.winery.model.tosca.TImport 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