diff --git a/xmla/bridge/pom.xml b/xmla/bridge/pom.xml
index da74dd5..98d4c84 100644
--- a/xmla/bridge/pom.xml
+++ b/xmla/bridge/pom.xml
@@ -68,5 +68,11 @@
0.0.1-SNAPSHOT
test
+
+ org.eclipse.daanse
+ org.eclipse.daanse.xmla.csdl.model.v2.edm
+ 0.0.1-SNAPSHOT
+ compile
+
diff --git a/xmla/bridge/src/main/java/org/eclipse/daanse/olap/xmla/bridge/discover/CSDLUtils.java b/xmla/bridge/src/main/java/org/eclipse/daanse/olap/xmla/bridge/discover/CSDLUtils.java
new file mode 100644
index 0000000..596eb12
--- /dev/null
+++ b/xmla/bridge/src/main/java/org/eclipse/daanse/olap/xmla/bridge/discover/CSDLUtils.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2025 Contributors to the Eclipse Foundation.
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * SmartCity Jena - initial
+ * Stefan Bischof (bipolis.org) - initial
+ */
+package org.eclipse.daanse.olap.xmla.bridge.discover;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.eclipse.daanse.olap.api.element.Catalog;
+import org.eclipse.daanse.olap.api.element.Cube;
+import org.eclipse.daanse.olap.api.element.Dimension;
+import org.eclipse.daanse.olap.api.element.Hierarchy;
+import org.eclipse.daanse.olap.api.element.Level;
+import org.eclipse.daanse.olap.api.element.Member;
+import org.eclipse.daanse.olap.common.StandardProperty;
+import org.eclipse.daanse.xmla.csdl.model.v2.bi.BiFactory;
+import org.eclipse.daanse.xmla.csdl.model.v2.bi.TEntityContainer;
+import org.eclipse.daanse.xmla.csdl.model.v2.bi.TEntitySet;
+import org.eclipse.daanse.xmla.csdl.model.v2.bi.TEntityType;
+import org.eclipse.daanse.xmla.csdl.model.v2.bi.THierarchy;
+import org.eclipse.daanse.xmla.csdl.model.v2.bi.TLevel;
+import org.eclipse.daanse.xmla.csdl.model.v2.bi.TMeasure;
+import org.eclipse.daanse.xmla.csdl.model.v2.edm.EdmFactory;
+import org.eclipse.daanse.xmla.csdl.model.v2.edm.EntityContainerType;
+import org.eclipse.daanse.xmla.csdl.model.v2.edm.EntitySetType;
+import org.eclipse.daanse.xmla.csdl.model.v2.edm.TEntityKeyElement;
+import org.eclipse.daanse.xmla.csdl.model.v2.edm.TEntityProperty;
+import org.eclipse.daanse.xmla.csdl.model.v2.edm.TPropertyRef;
+import org.eclipse.daanse.xmla.csdl.model.v2.edm.TSchema;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+
+public class CSDLUtils {
+ private static EdmFactory edmFactory = EdmFactory.eINSTANCE;
+ private static BiFactory biFactory = BiFactory.eINSTANCE;
+
+ private static final String csdlMd3 = """
+
+
+
+ %s
+
+ %s
+
+
+ %s
+
+ """;
+
+ private static final String csdlMd4 = """
+
+
+
+
+
+ """;
+
+ public static TSchema getCSDLModel(Catalog catalog, Optional perspectiveName) {
+ if (perspectiveName.isPresent()) {
+ String cubeName = perspectiveName.get();
+ Optional oCube = catalog.getCubes().stream().filter(c -> cubeName.equals(c.getName())).findFirst();
+ if (oCube.isPresent()) {
+ Cube cube = oCube.get();
+ TSchema schema = edmFactory.createTSchema();
+ schema.setNamespace("Model");
+ schema.setAlias("Model");
+
+ EntityContainerType container = edmFactory.createEntityContainerType();
+ container.setName(catalog.getName());
+
+ TEntityContainer biContainer = biFactory.createTEntityContainer();
+ biContainer.setCaption(cube.getName());
+ biContainer.setCulture("de-DE");
+ container.setBiEntityContainer(biContainer);
+
+
+ List measures = cube.getMeasures();
+ if (measures != null) {
+ for (Member member : measures) {
+ EntitySetType entitySet = edmFactory.createEntitySetType();
+ entitySet.setName(member.getUniqueName());
+ entitySet.setEntityType("Model." + member.getUniqueName());
+ TEntitySet biEntitySet = biFactory.createTEntitySet();
+ biEntitySet.setCaption(member.getCaption());
+ entitySet.setBiEntitySet(biEntitySet);
+ container.getEntitySet().add(entitySet);
+
+ org.eclipse.daanse.xmla.csdl.model.v2.edm.TEntityType measureSumType = edmFactory.createTEntityType();
+ measureSumType.setName(member.getUniqueName());
+
+ TEntityType biMeasureSumType = biFactory.createTEntityType();
+ biMeasureSumType.setContents(member.getUniqueName());
+ measureSumType.setBiEntityType(biMeasureSumType);
+
+ TEntityProperty valueProperty = edmFactory.createTEntityProperty();
+ valueProperty.setName(member.getUniqueName());
+ String type = getType(member.getPropertyValue(StandardProperty.DATATYPE.getName()));
+ valueProperty.setType(type);
+ valueProperty.setNullable(false);
+
+ TMeasure biValueMeasure = biFactory.createTMeasure();
+ biValueMeasure.setCaption(member.getUniqueName());
+ biValueMeasure.setHidden(false);
+ valueProperty.setBiMeasure(biValueMeasure);
+
+ measureSumType.getProperty().add(valueProperty);
+ schema.getEntityType().add(measureSumType);
+ }
+ }
+
+ List hierarchies = cube.getHierarchies();
+ if (hierarchies != null) {
+ for (Hierarchy hierarchy : hierarchies) {
+ EntitySetType entitySetHierarchy = edmFactory.createEntitySetType();
+ entitySetHierarchy.setName(hierarchy.getUniqueName());
+ entitySetHierarchy.setEntityType("Model." + hierarchy.getUniqueName());
+
+ TEntitySet biEntitySetHierarchy = biFactory.createTEntitySet();
+ biEntitySetHierarchy.setCaption(hierarchy.getCaption());
+
+ entitySetHierarchy.setBiEntitySet(biEntitySetHierarchy);
+
+ container.getEntitySet().add(entitySetHierarchy);
+
+ org.eclipse.daanse.xmla.csdl.model.v2.edm.TEntityType hierarchyType = edmFactory.createTEntityType();
+ hierarchyType.setName(hierarchy.getUniqueName());
+
+ List levels = new ArrayList<>();
+
+ List extends Level> ls = hierarchy.getLevels();
+ if (ls != null) {
+ for (Level l : ls) {
+ TLevel tLevel = biFactory.createTLevel();
+ tLevel.setName(l.getUniqueName());
+ tLevel.setCaption(l.getCaption());
+ tLevel.setReferenceName(l.getUniqueName());
+ levels.add(tLevel);
+
+ TEntityProperty levelProperty = edmFactory.createTEntityProperty();
+ levelProperty.setName(l.getUniqueName());
+ levelProperty.setType("String"); //TODO need get type from level
+ levelProperty.setNullable(false);
+ hierarchyType.getProperty().add(levelProperty);
+ }
+ }
+
+ THierarchy hierarchyTHierarchy = biFactory.createTHierarchy();
+ hierarchyTHierarchy.setCaption(hierarchy.getCaption());
+ hierarchyTHierarchy.setName(hierarchy.getUniqueName());
+ hierarchyTHierarchy.setReferenceName(hierarchy.getUniqueName());
+
+ hierarchyTHierarchy.getLevel().addAll(levels);
+
+ TEntityType hierarchyTEntityType = biFactory.createTEntityType();
+ hierarchyTEntityType.setContents(hierarchy.getUniqueName());
+ hierarchyTEntityType.getHierarchy().add(hierarchyTHierarchy);
+
+ hierarchyType.setBiEntityType(hierarchyTEntityType);
+
+ TEntityProperty hierarchyKeyProperty = edmFactory.createTEntityProperty();
+ hierarchyKeyProperty.setName(hierarchy.getUniqueName());
+ hierarchyKeyProperty.setType("Int32");
+ hierarchyKeyProperty.setNullable(false);
+
+ TPropertyRef hierarchyPropertyRef = edmFactory.createTPropertyRef();
+ hierarchyPropertyRef.setName(hierarchy.getUniqueName());
+
+ TEntityKeyElement key = edmFactory.createTEntityKeyElement();
+ key.getPropertyRef().add(hierarchyPropertyRef);
+
+ hierarchyType.getProperty().add(hierarchyKeyProperty);
+
+ schema.getEntityType().add(hierarchyType);
+ }
+ }
+ return schema;
+ }
+ }
+ return edmFactory.createTSchema();
+ }
+
+ private static String getType(Object propertyValue) {
+ if (propertyValue != null && propertyValue instanceof String value) {
+ switch (value) {
+ case "UNDEFINED":
+ case "String":
+ return "String";
+ case "NUMERIC":
+ return "Numeric";
+ case "Integer":
+ return "Int32";
+ case "Boolean":
+ return "Boolean";
+ case "Date":
+ return "Date";
+ case "Time":
+ return "Time";
+ case "Timestamp":
+ return "Timestamp";
+ default:
+ return "String";
+ }
+ }
+ return "String";
+ }
+
+ public static String getCSDLModelAsString(TSchema schema) {
+ try {
+ return serializeToXml(schema);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String getCSDL(Catalog catalog, Optional perspectiveName) {
+ if (perspectiveName.isPresent()) {
+ String cubeName = perspectiveName.get();
+ Optional oCube = catalog.getCubes().stream().filter(c -> cubeName.equals(c.getName())).findFirst();
+ if (oCube.isPresent()) {
+ return String.format(csdlMd3, cubeName, getEntitySets(oCube.get()), getEntityTypes(oCube.get()));
+ }
+ }
+ return String.format(csdlMd4);
+ }
+
+ private static String serializeToXml(EObject eObject) throws IOException {
+ ResourceSetImpl resourceSet = new ResourceSetImpl();
+ Resource resource = resourceSet.createResource(URI.createURI("temp.xml"));
+ resource.getContents().add(eObject);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Map options = new HashMap<>();
+ options.put(XMLResource.OPTION_ENCODING, "UTF-8");
+ options.put(XMLResource.OPTION_FORMATTED, Boolean.TRUE);
+ options.put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
+
+ resource.save(baos, options);
+
+ resource.getContents().clear();
+ resourceSet.getResources().remove(resource);
+
+ return baos.toString("UTF-8");
+ }
+
+ private static String getEntityTypes(Cube cube) {
+ StringBuilder sb = new StringBuilder();
+ boolean flag = true;
+ for (Dimension dimension : cube.getDimensions()) {
+ for (Hierarchy hierarchy : dimension.getHierarchies()) {
+ if (flag) {
+ flag = false;
+ } else {
+ sb.append(System.lineSeparator());
+ }
+ sb.append("")
+ .append(System.lineSeparator());
+ sb.append(" ")
+ .append(System.lineSeparator())
+ .append(" ")
+ .append(System.lineSeparator())
+ .append(" ")
+ .append(System.lineSeparator());
+
+ sb.append(" ")
+ .append(System.lineSeparator())
+ .append("")
+ .append(System.lineSeparator());
+
+ for (Level level : hierarchy.getLevels()) {
+ sb.append(" ")
+ .append(System.lineSeparator())
+ .append("");
+ }
+ sb.append(System.lineSeparator());
+ sb.append(" ");
+ sb.append(System.lineSeparator());
+ for (Level level : hierarchy.getLevels()) {
+ sb.append(" ");
+ sb.append(System.lineSeparator());
+ sb.append(" ");
+ sb.append(System.lineSeparator());
+ sb.append(" ");
+ sb.append(System.lineSeparator());
+ sb.append(" ");
+ sb.append(System.lineSeparator());
+ sb.append(" ");
+ sb.append(System.lineSeparator());
+ }
+ sb.append(" ");
+ sb.append(System.lineSeparator());
+ sb.append("");
+
+ }
+ }
+ for (Member member : cube.getMeasures()) {
+ if (flag) {
+ flag = false;
+ } else {
+ sb.append(System.lineSeparator());
+ }
+ sb.append("")
+ .append(System.lineSeparator());
+ sb.append(" ")
+ .append(System.lineSeparator())
+ .append(" ")
+ .append(System.lineSeparator())
+ .append(" ")
+ .append(System.lineSeparator());
+
+ sb.append(" ")
+ //.append(System.lineSeparator())
+ //.append(" ")
+ .append(System.lineSeparator())
+ .append("");
+ sb.append(System.lineSeparator())
+ .append("");
+ }
+ return sb.toString();
+ }
+
+ private static String getEntitySets(Cube cube) {
+ StringBuilder sb = new StringBuilder();
+ boolean flag = true;
+ for (Dimension dimension : cube.getDimensions()) {
+ for (Hierarchy hierarchy : dimension.getHierarchies()) {
+ if (flag) {
+ flag = false;
+ } else {
+ sb.append(System.lineSeparator());
+ }
+ sb.append("")
+ .append(System.lineSeparator())
+ .append("");
+ }
+ }
+ if (cube.getMeasures() != null && cube.getMeasures().size() > 0) {
+ for (Member member : cube.getMeasures()) {
+ if (flag) {
+ flag = false;
+ } else {
+ sb.append(System.lineSeparator());
+ }
+ sb.append("")
+ .append(System.lineSeparator())
+ .append("");
+ }
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/xmla/bridge/src/main/java/org/eclipse/daanse/olap/xmla/bridge/discover/DelegatingDiscoverService.java b/xmla/bridge/src/main/java/org/eclipse/daanse/olap/xmla/bridge/discover/DelegatingDiscoverService.java
index e4c02b8..e2d44f3 100644
--- a/xmla/bridge/src/main/java/org/eclipse/daanse/olap/xmla/bridge/discover/DelegatingDiscoverService.java
+++ b/xmla/bridge/src/main/java/org/eclipse/daanse/olap/xmla/bridge/discover/DelegatingDiscoverService.java
@@ -272,10 +272,8 @@ public List xmlMetaData(DiscoverXmlMetaDataReque
@Override
public List csdlMetaData(DiscoverCsdlMetaDataRequest request,
RequestMetaData metaData) {
- //return otherSchemaService.csdlMetaData(request, metaData);
- //TODO
- return null;
+ return otherSchemaService.csdlMetaData(request, metaData);
}
}
diff --git a/xmla/bridge/src/main/java/org/eclipse/daanse/olap/xmla/bridge/discover/OtherDiscoverService.java b/xmla/bridge/src/main/java/org/eclipse/daanse/olap/xmla/bridge/discover/OtherDiscoverService.java
index 8f67c9d..bd548a8 100644
--- a/xmla/bridge/src/main/java/org/eclipse/daanse/olap/xmla/bridge/discover/OtherDiscoverService.java
+++ b/xmla/bridge/src/main/java/org/eclipse/daanse/olap/xmla/bridge/discover/OtherDiscoverService.java
@@ -26,7 +26,11 @@
import java.util.Set;
import org.eclipse.daanse.olap.api.Context;
+import org.eclipse.daanse.olap.api.DataTypeJdbc;
import org.eclipse.daanse.olap.api.element.Catalog;
+import org.eclipse.daanse.olap.api.element.DatabaseColumn;
+import org.eclipse.daanse.olap.api.element.DatabaseSchema;
+import org.eclipse.daanse.olap.api.element.DatabaseTable;
import org.eclipse.daanse.olap.xmla.bridge.ContextGroupXmlaServiceConfig;
import org.eclipse.daanse.olap.xmla.bridge.ContextListSupplyer;
import org.eclipse.daanse.xmla.api.PropertyDefinition;
@@ -47,6 +51,7 @@
import org.eclipse.daanse.xmla.api.discover.dbschema.tables.DbSchemaTablesRequest;
import org.eclipse.daanse.xmla.api.discover.dbschema.tablesinfo.DbSchemaTablesInfoRequest;
import org.eclipse.daanse.xmla.api.discover.discover.csdlmetadata.DiscoverCsdlMetaDataRequest;
+import org.eclipse.daanse.xmla.api.discover.discover.csdlmetadata.DiscoverCsdlMetaDataResponseRow;
import org.eclipse.daanse.xmla.api.discover.discover.datasources.DiscoverDataSourcesRequest;
import org.eclipse.daanse.xmla.api.discover.discover.datasources.DiscoverDataSourcesResponseRow;
import org.eclipse.daanse.xmla.api.discover.discover.enumerators.DiscoverEnumeratorsRequest;
@@ -75,6 +80,8 @@
import org.eclipse.daanse.xmla.api.discover.mdschema.properties.MdSchemaPropertiesRequest;
import org.eclipse.daanse.xmla.api.discover.mdschema.sets.MdSchemaSetsRequest;
import org.eclipse.daanse.xmla.api.xmla.Restriction;
+import org.eclipse.daanse.xmla.csdl.model.v2.edm.TSchema;
+import org.eclipse.daanse.xmla.model.record.discover.discover.csdlmetadata.DiscoverCsdlMetaDataResponseRowR;
import org.eclipse.daanse.xmla.model.record.discover.discover.datasources.DiscoverDataSourcesResponseRowR;
import org.eclipse.daanse.xmla.model.record.discover.discover.enumerators.DiscoverEnumeratorsResponseRowR;
import org.eclipse.daanse.xmla.model.record.discover.discover.keywords.DiscoverKeywordsResponseRowR;
@@ -288,7 +295,7 @@ public List discoverSchemaRowsets(DiscoverSche
}
}
result.add(new DiscoverSchemaRowsetsResponseRowR(o.name(), Optional.ofNullable(o.guid()),
- Optional.ofNullable(restrictions), Optional.of((desc == null) ? "" : desc), Optional.empty()));
+ Optional.ofNullable(restrictions), Optional.ofNullable(desc), Optional.of(7l)));
}
}
return result;
@@ -328,6 +335,37 @@ public List xmlMetaData(DiscoverXmlMetaDataReque
return result;
}
+ public List csdlMetaData(DiscoverCsdlMetaDataRequest request,
+ RequestMetaData metaData) {
+ List result = new ArrayList<>();
+ Optional catalogName = request.restrictions().catalogName();
+ Optional perspectiveName = request.restrictions().perspectiveName();
+ if (!catalogName.isPresent()) {
+ catalogName = request.properties().catalog();
+ }
+ if (catalogName.isPresent()) {
+ Optional oCatalog = contextsListSupplyer.tryGetFirstByName(catalogName.get(), metaData.sessionId());
+ if (oCatalog.isPresent()) {
+ Catalog catalog = oCatalog.get();
+
+ if (catalog != null) {
+ TSchema schema = CSDLUtils.getCSDLModel(catalog, perspectiveName);
+ //result.add(new DiscoverCsdlMetaDataResponseRowR(CSDLUtils.getCSDL(catalog, perspectiveName)));
+ result.add(new DiscoverCsdlMetaDataResponseRowR(CSDLUtils.getCSDLModelAsString(schema)));
+ }
+ }
+ } else {
+ List cs = contextsListSupplyer.get(metaData.sessionId());
+ if (cs != null) {
+ Catalog catalog = cs.get(0);
+ TSchema schema = CSDLUtils.getCSDLModel(catalog, Optional.empty());
+ //result.add(new DiscoverCsdlMetaDataResponseRowR(CSDLUtils.getCSDL(catalog, Optional.empty())));
+
+ }
+ }
+ return result;
+ }
+
private String getOperationDescription(String name) {
switch (name) {
case "DBSCHEMA_CATALOGS":
diff --git a/xmla/bridge/test.bndrun b/xmla/bridge/test.bndrun
index 8241254..b504317 100644
--- a/xmla/bridge/test.bndrun
+++ b/xmla/bridge/test.bndrun
@@ -73,11 +73,20 @@
org.eclipse.daanse.olap.xmla.bridge-tests;version='[0.0.1,0.0.2)',\
org.eclipse.daanse.sql.guard.api;version='[0.0.1,0.0.2)',\
org.eclipse.daanse.xmla.api;version='[0.0.1,0.0.2)',\
+ org.eclipse.daanse.xmla.csdl.model.v2.an;version='[0.0.1,0.0.2)',\
+ org.eclipse.daanse.xmla.csdl.model.v2.bi;version='[0.0.1,0.0.2)',\
+ org.eclipse.daanse.xmla.csdl.model.v2.cg;version='[0.0.1,0.0.2)',\
+ org.eclipse.daanse.xmla.csdl.model.v2.edm;version='[0.0.1,0.0.2)',\
org.eclipse.daanse.xmla.model.record;version='[0.0.1,0.0.2)',\
- org.mockito.junit-jupiter;version='[4.9.0,4.9.1)',\
- org.mockito.mockito-core;version='[4.9.0,4.9.1)',\
+ org.eclipse.emf.common;version='[2.44.0,2.44.1)',\
+ org.eclipse.emf.ecore;version='[2.41.0,2.41.1)',\
+ org.eclipse.emf.ecore.xmi;version='[2.39.0,2.39.1)',\
+ org.eclipse.fennec.emf.osgi.api;version='[1.0.0,1.0.1)',\
+ org.mockito.junit-jupiter;version='[5.18.0,5.18.1)',\
+ org.mockito.mockito-core;version='[5.18.0,5.18.1)',\
org.objenesis;version='[3.3.0,3.3.1)',\
org.opentest4j;version='[1.3.0,1.3.1)',\
+ org.osgi.service.cm;version='[1.6.1,1.6.2)',\
org.osgi.service.component;version='[1.5.1,1.5.2)',\
org.osgi.test.common;version='[1.3.0,1.3.1)',\
org.osgi.test.junit5;version='[1.3.0,1.3.1)',\