Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
13194ac
temp
kiph-soptim May 21, 2026
19b638d
temp
kiph-soptim May 26, 2026
278bba1
Merge remote-tracking branch 'origin/main' into feature/RDFA-344-Cros…
kiph-soptim May 29, 2026
aeed5ad
temp
kiph-soptim Jun 1, 2026
9dcd36c
Merge remote-tracking branch 'origin/main' into feature/RDFA-344-Cros…
kiph-soptim Jun 10, 2026
096adfa
solved after merge problems
kiph-soptim Jun 10, 2026
1a6ec24
fixed license header
kiph-soptim Jun 10, 2026
c4a1d5f
deleted class
kiph-soptim Jun 10, 2026
05ae9e9
added option to disable colored properties
kiph-soptim Jun 10, 2026
c157b2c
added color to association edges and fixed tests
kiph-soptim Jun 11, 2026
2d59a0c
fixes
kiph-soptim Jun 11, 2026
53a21f7
fixes
kiph-soptim Jun 11, 2026
b93d0a2
ignore not needed fields
kiph-soptim Jun 11, 2026
29068ac
fix
kiph-soptim Jun 11, 2026
498f6bc
fix
kiph-soptim Jun 11, 2026
0db756b
Merge branch 'main' into feature/RDFA-344-Cross-profile-diagrams
kiph-soptim Jun 11, 2026
7660c9b
fix
kiph-soptim Jun 11, 2026
0a8d95d
fix
kiph-soptim Jun 11, 2026
9b6babb
fixed Missing Override annotation
kiph-soptim Jun 11, 2026
fd48b2d
format
kiph-soptim Jun 11, 2026
7b30326
Revert "format"
kiph-soptim Jun 11, 2026
f892cab
Revert "fixed Missing Override annotation"
kiph-soptim Jun 11, 2026
cbbd73f
Merge branch 'main' into feature/RDFA-344-Cross-profile-diagrams
kiph-soptim Jun 11, 2026
82ba9a0
improved loading time of the merged class editor
kiph-soptim Jun 11, 2026
38f6664
added show in diagram to merged classes
kiph-soptim Jun 12, 2026
fcec506
refactoring
kiph-soptim Jun 12, 2026
110ee82
added tests
kiph-soptim Jun 12, 2026
cab90dc
updated README.md
kiph-soptim Jun 12, 2026
55a872b
Merge branch 'main' into feature/RDFA-344-Cross-profile-diagrams
kiph-soptim Jun 12, 2026
162dd47
format
kiph-soptim Jun 12, 2026
5352a11
Merge branch 'main' into feature/RDFA-344-Cross-profile-diagrams
kiph-soptim Jun 16, 2026
f8e6d3b
Merge branch 'main' into feature/RDFA-344-Cross-profile-diagrams
kiph-soptim Jun 16, 2026
33fc270
removed debug messages
kiph-soptim Jun 17, 2026
e86aeca
fixed single click expands merge view
kiph-soptim Jun 17, 2026
a2a9e9d
fixed enum entry mapping
kiph-soptim Jun 17, 2026
aab94ff
Merge branch 'main' into feature/RDFA-344-Cross-profile-diagrams
kiph-soptim Jun 18, 2026
f661899
adjusted tests
kiph-soptim Jun 18, 2026
2d93aea
selectedClassUUID and selectedClassType combined to selectedClass
kiph-soptim Jun 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ For the complete documentation, see the [docs site](https://rdfarchitect.soptim.

- Import and export RDF schemas and CIM extensions
- Visualize class structures via UML diagrams
- create custom diagrams containing classes from different packages or even profiles
- Create custom diagrams containing classes from different packages or even profiles
- Merge View — Visualize and inspect classes from multiple profiles across a dataset in a single unified diagram
- Edit classes, attributes, associations, enum entries, and notes
- Share diagrams as a complete, read-friendly reference of classes, relations, notes, and constraints
- Schema migration between CIM versions and extensions
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2024-2026 SOPTIM AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.rdfarchitect.api.controller.datasets.diagrams;

import io.swagger.v3.oas.annotations.Parameter;

import lombok.RequiredArgsConstructor;

import org.rdfarchitect.api.dto.crossProfileDiagram.CrossProfileDiagramColorDataDTO;
import org.rdfarchitect.services.diagrams.CrossProfileColorUseCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/datasets/{datasetName}/crossprofilediagramColors")
@RequiredArgsConstructor
public class CrossProfileDiagramColorRestController {

private static final Logger logger =
LoggerFactory.getLogger(CrossProfileDiagramColorRestController.class);

private final CrossProfileColorUseCase colorUseCase;

@GetMapping
public CrossProfileDiagramColorDataDTO getCrossProfileColors(
@Parameter(description = "The name/url of the inquirer.")
@RequestHeader(
value = HttpHeaders.ORIGIN,
required = false,
defaultValue = "unknown")
String originURL,
@Parameter(description = "The literal name of the dataset.") @PathVariable
String datasetName) {
logger.info(
"Received GET request: \"/api/datasets/{{}}/crossprofilediagramColors\" from \"{}\"",
datasetName,
originURL);

var result = colorUseCase.getCrossProfileColors(datasetName);

logger.info(
"Sending response to GET request: \"/api/datasets/{{}}/crossprofilediagramColors\" from \"{}\"",
datasetName,
originURL);
return result;
}

@PutMapping
public void updateCrossProfileColors(
@Parameter(description = "The name/url of the inquirer.")
@RequestHeader(
value = HttpHeaders.ORIGIN,
required = false,
defaultValue = "unknown")
String originURL,
@Parameter(description = "The literal name of the dataset.") @PathVariable
String datasetName,
@RequestBody CrossProfileDiagramColorDataDTO colorData) {

logger.info(
"Received PUT request: \"/api/datasets/{{}}/crossprofilediagramColors\" from \"{}\"",
datasetName,
originURL);

colorUseCase.replaceCrossProfileColors(datasetName, colorData);

logger.info(
"Sending response to PUT request: \"/api/datasets/{{}}/crossprofilediagramColors\" from \"{}\"",
datasetName,
originURL);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2024-2026 SOPTIM AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.rdfarchitect.api.controller.datasets.diagrams;

import io.swagger.v3.oas.annotations.Parameter;

import lombok.RequiredArgsConstructor;

import org.rdfarchitect.database.DatabasePort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/datasets/{datasetName}/crossprofilediagramID")
@RequiredArgsConstructor
public class CrossProfileDiagramIDController {

private static final Logger logger =
LoggerFactory.getLogger(CrossProfileDiagramIDController.class);

private final DatabasePort databasePort;

@GetMapping
public String getCrossProfileRenderingData(
@Parameter(description = "The name/url of the inquirer.")
@RequestHeader(
value = HttpHeaders.ORIGIN,
required = false,
defaultValue = "unknown")
String originURL,
@Parameter(description = "The literal name of the dataset.") @PathVariable
String datasetName) {
logger.info(
"Received GET request: \"/api/datasets/{{}}/crossprofilediagram\" from \"{}\"",
datasetName,
originURL);

logger.info(
"Sending response to GET request: \"/api/datasets/{{}}/crossprofilediagram\" from \"{}\"",
datasetName,
originURL);
return databasePort.getCrossProfileDiagramUUID(datasetName).toString();
Comment thread
kiph-soptim marked this conversation as resolved.
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2024-2026 SOPTIM AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.rdfarchitect.api.controller.datasets.diagrams;

import io.swagger.v3.oas.annotations.Parameter;

import lombok.RequiredArgsConstructor;

import org.rdfarchitect.api.dto.rendering.RenderingDataDTO;
import org.rdfarchitect.database.DatabasePort;
import org.rdfarchitect.models.cim.rendering.RenderCIMCollectionUseCase;
import org.rdfarchitect.services.diagrams.GetCustomDiagramsUseCase;
import org.rdfarchitect.services.rendering.DiagramToCIMCollectionConverterUseCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/datasets/{datasetName}/crossprofilediagramRendering")
@RequiredArgsConstructor
public class CrossProfileDiagramRenderingRestController {

private static final Logger logger =
LoggerFactory.getLogger(CrossProfileDiagramRenderingRestController.class);

private final DiagramToCIMCollectionConverterUseCase converter;

private final RenderCIMCollectionUseCase renderer;

private final GetCustomDiagramsUseCase getCustomDiagramsUseCase;

private final DatabasePort databasePort;

@GetMapping
public RenderingDataDTO getCrossProfileRenderingData(
@Parameter(description = "The name/url of the inquirer.")
@RequestHeader(
value = HttpHeaders.ORIGIN,
required = false,
defaultValue = "unknown")
String originURL,
@Parameter(description = "The literal name of the dataset.") @PathVariable
String datasetName) {
logger.info(
"Received GET request: \"/api/datasets/{{}}/crossprofilediagramRendering\" from \"{}\"",
datasetName,
originURL);

var crossProfileDiagram =
getCustomDiagramsUseCase.getCrossProfileDiagram(datasetName, true, true);

var cimCollection = converter.convert(crossProfileDiagram);

var result =
renderer.renderGlobalUML(
cimCollection,
datasetName,
databasePort.getCrossProfileDiagramUUID(datasetName));

Comment on lines +69 to +79

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are 2 separate transactions. preferably they are all called in the same use case in one transaction

logger.info(
"Sending response to GET request: \"/api/datasets/{{}}/crossprofilediagramRendering\" from \"{}\"",
datasetName,
originURL);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2024-2026 SOPTIM AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.rdfarchitect.api.controller.datasets.diagrams;

import io.swagger.v3.oas.annotations.Parameter;

import lombok.RequiredArgsConstructor;

import org.rdfarchitect.api.dto.crossProfileDiagram.CrossProfileDiagramDTO;
import org.rdfarchitect.services.diagrams.GetCustomDiagramsUseCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/datasets/{datasetName}/crossprofilediagram")
@RequiredArgsConstructor
public class CrossProfileDiagramRestController {

private static final Logger logger =
LoggerFactory.getLogger(CrossProfileDiagramRestController.class);

private final GetCustomDiagramsUseCase getCustomDiagramsUseCase;

@GetMapping
public CrossProfileDiagramDTO getCrossProfileRenderingData(
@Parameter(description = "The name/url of the inquirer.")
@RequestHeader(
value = HttpHeaders.ORIGIN,
required = false,
defaultValue = "unknown")
String originURL,
@Parameter(description = "The literal name of the dataset.") @PathVariable
String datasetName) {
logger.info(
"Received GET request: \"/api/datasets/{{}}/crossprofilediagram\" from \"{}\"",
datasetName,
originURL);

var result = getCustomDiagramsUseCase.getCrossProfileDiagram(datasetName, false, false);

logger.info(
"Sending response to GET request: \"/api/datasets/{{}}/crossprofilediagram\" from \"{}\"",
datasetName,
originURL);
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public interface ClassUMLAdaptedMapper {
List<ClassUMLAdaptedDTO> toDTOList(List<CIMClassUMLAdapted> cimClassList);

@Mapping(target = "uri", source = ".")
@Mapping(target = "graphUri", ignore = true)
CIMClassUMLAdapted toCIMObject(ClassUMLAdaptedDTO dto);

List<CIMClassUMLAdapted> toCIMObjectList(List<ClassUMLAdaptedDTO> dtoList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public interface AssociationMapper {
@Mapping(target = "uri", source = "dto")
@Mapping(target = "domain", source = "dto")
@Mapping(target = "inverseRoleName", expression = "java(buildInverseRoleName(inverseUri))")
@Mapping(target = "graphUri", ignore = true)
@Mapping(target = "color", ignore = true)
CIMAssociation toCIMObject(AssociationDTO dto, String inverseUri);

default String toDomain(URI value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ default String map(URI value) {
"java(new CIMSStereotype(\"http://iec.ch/TC57/NonStandard/UML#attribute\"))")
@Mapping(target = "fixedValue", source = ".")
@Mapping(target = "defaultValue", source = ".")
@Mapping(target = "graphUri", ignore = true)
@Mapping(target = "color", ignore = true)
CIMAttribute toCIMObject(AttributeDTO dto);

List<CIMAttribute> toCIMObjectList(List<AttributeDTO> dtoList);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2024-2026 SOPTIM AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.rdfarchitect.api.dto.crossProfileDiagram;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.UUID;

@Data
@AllArgsConstructor
public class ClassSourceDTO {
private UUID classUUID;
private String graphUri;
}
Loading