diff --git a/java/bundles/org.eclipse.set.basis/META-INF/MANIFEST.MF b/java/bundles/org.eclipse.set.basis/META-INF/MANIFEST.MF index c9947b4f55..bfe4bb17b1 100644 --- a/java/bundles/org.eclipse.set.basis/META-INF/MANIFEST.MF +++ b/java/bundles/org.eclipse.set.basis/META-INF/MANIFEST.MF @@ -35,6 +35,8 @@ Export-Package: org.eclipse.set.basis, org.eclipse.set.basis.viewgroups Import-Package: com.google.common.collect, org.apache.commons.lang3, + org.eclipse.core.databinding.observable, + org.eclipse.core.databinding.observable.value;version="[1.0.0,2.0.0)", org.eclipse.core.runtime, org.eclipse.e4.core.contexts, org.eclipse.e4.core.di, diff --git a/java/bundles/org.eclipse.set.basis/src/org/eclipse/set/basis/observable/SupplierObservableValue.java b/java/bundles/org.eclipse.set.basis/src/org/eclipse/set/basis/observable/SupplierObservableValue.java new file mode 100644 index 0000000000..4fb5f4b75e --- /dev/null +++ b/java/bundles/org.eclipse.set.basis/src/org/eclipse/set/basis/observable/SupplierObservableValue.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2026 DB InfraGO AG and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + */ +package org.eclipse.set.basis.observable; + +import java.util.function.Supplier; + +import org.eclipse.core.databinding.observable.value.WritableValue; + +/** + * Observable with Supplier to get value + * + * @author truong + * @param + * the value type + */ +public class SupplierObservableValue extends WritableValue { + + private final Supplier supplier; + + /** + * @param supplier + * the {@link Supplier} to get value + * @param valueType + * the value type + */ + public SupplierObservableValue(final Supplier supplier, + final Object valueType) { + super(supplier.get(), valueType); + this.supplier = supplier; + } + + /** + * Set value through supplier + */ + public void calculate() { + if (getRealm().isCurrent()) { + setValue(supplier.get()); + } else { + getRealm().asyncExec(() -> setValue(supplier.get())); + } + } + +} diff --git a/java/bundles/org.eclipse.set.feature.validation/META-INF/MANIFEST.MF b/java/bundles/org.eclipse.set.feature.validation/META-INF/MANIFEST.MF index 590e9c0b37..1e904bcedc 100644 --- a/java/bundles/org.eclipse.set.feature.validation/META-INF/MANIFEST.MF +++ b/java/bundles/org.eclipse.set.feature.validation/META-INF/MANIFEST.MF @@ -14,6 +14,9 @@ Import-Package: com.google.common.base;version="15.0.0", org.apache.commons.io.filefilter;version="2.15.0", org.apache.commons.text, org.apache.poi;version="5.0.0", + org.eclipse.core.databinding, + org.eclipse.core.databinding.observable.value, + org.eclipse.core.databinding.property.value, org.eclipse.core.runtime;version="3.5.0", org.eclipse.e4.core.contexts;version="1.7.0", org.eclipse.e4.core.di;version="1.7.0", @@ -34,6 +37,8 @@ Import-Package: com.google.common.base;version="15.0.0", org.eclipse.emf.ecore.xmi, org.eclipse.emf.edit.domain, org.eclipse.emf.edit.provider, + org.eclipse.jface.databinding.swt, + org.eclipse.jface.databinding.swt.typed, org.eclipse.jface.dialogs, org.eclipse.jface.layout, org.eclipse.jface.operation, @@ -49,6 +54,7 @@ Import-Package: com.google.common.base;version="15.0.0", org.eclipse.set.basis.extensions, org.eclipse.set.basis.files, org.eclipse.set.basis.guid, + org.eclipse.set.basis.observable, org.eclipse.set.basis.part, org.eclipse.set.basis.viewgroups, org.eclipse.set.core.services.cache, diff --git a/java/bundles/org.eclipse.set.feature.validation/OSGI-INF/l10n/bundle.properties b/java/bundles/org.eclipse.set.feature.validation/OSGI-INF/l10n/bundle.properties index af832071fa..b3df209fde 100644 --- a/java/bundles/org.eclipse.set.feature.validation/OSGI-INF/l10n/bundle.properties +++ b/java/bundles/org.eclipse.set.feature.validation/OSGI-INF/l10n/bundle.properties @@ -19,9 +19,44 @@ NoSubworks=Kein Untergewerk vorhanden. ExportValidationMsg=Export als CSV ExportValidationTitleMsg=Export als CSV ProgressMsg=Öffne Validierungssicht -ShowValidationTableMsg=Zeige Meldungen in neuer Sicht +ShowValidationTableMsg=Zeige Meldungen SourceMsg=Quelltext +ValidationReport_Report_Title=Validierungsmeldungen +ValidationReport_Report_PlaningRegion=Meldungen in Planungsbereich +ValidationReport_Report_ViewRegion=Meldungen in Betrachstungsbereich +ValidationReport_ModelInfo=Modellinformationen +ValidationReport_FunctionalModelInfo=Fachliche Modellinformationen + +ValidationReport_Supported_Version=Unterstütztes XML-Schema +ValidationReport_Used_Version=Verwendetes XML-Schema (in Datei) +ValidationReport_Version_PlanPro=PlanPro +ValidationReport_Version_Signalbegriffe=Signalbegriffe + + +ValidationReport_Validity=Gültigkeit +ValidationReport_Validity_XSD_VALID=XSD-Gültigkeit +ValidationReport_Validity_EMF_VALID=EMF-Gültigkeit +ValidationReport_Validity_ModelLoaded=Verarbeitbar + +ValidationReport_Messages=Validierungsmeldungen +ValidationReport_Subworks=Untergewerke +ValidationReport_Subwork_Model_Content=Enthalten + +ValidationReport_GeladeneDatei=Geladene Datei +ValidationReport_GeladeneDatei_DateiName=Dateiname +ValidationReport_GeladeneDatei_TimeStamp=Zeitstempel +ValidationReport_GeladeneDatei_MD5=MD5 +ValidationReport_GeladeneDatei_GUID=GUID +ValidationReport_Metadata=Wesentliche Planungsmetadaten +ValidationReport_Metadata_Location=führende Örtlichkeit +ValidationReport_Metadata_Route=führende Strecke +ValidationReport_Metadata_BuildDesignation=Bauzustand Kurzbezeichnung +ValidationReport_Metadata_Index=Index +ValidationReport_Metadata_LfdNr=Laufende Nummer + +ValidationReport_ContainerContents =PlanPro-Container + ValidationReport_Report_Title=Validierungsmeldungen ValidationReport_ModelInfo=Modellinformationen ValidationReport_FunctionalModelInfo=Fachliche Modellinformationen diff --git a/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/LayoutInfoRequired.java b/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/LayoutInfoRequired.java index d54978ad07..5b193be290 100644 --- a/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/LayoutInfoRequired.java +++ b/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/LayoutInfoRequired.java @@ -23,7 +23,7 @@ */ @Component(immediate = true, service = CustomValidator.class) public class LayoutInfoRequired extends AbstractCustomValidator { - public static final String LAYOUT_VALIDATION_TYPE = "Metainformationen"; //$NON-NLS-1$ + public static final String METADATA_VALIDATION_TYPE = "Metainformationen"; //$NON-NLS-1$ @Override public void validate(final ToolboxFile toolboxFile, @@ -55,7 +55,7 @@ private CustomValidationProblemImpl layoutMissing() { @Override public String validationType() { - return LAYOUT_VALIDATION_TYPE; + return METADATA_VALIDATION_TYPE; } } diff --git a/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/Messages.java b/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/Messages.java index 66f77fde25..f75b31e940 100644 --- a/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/Messages.java +++ b/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/Messages.java @@ -356,4 +356,43 @@ public class Messages { */ public String ValidationReport_Report_Title; + /** + * Meldungen in Planungsbereich + */ + public String ValidationReport_Report_PlaningRegion; + + /** + * Meldungen in Betrachstungsbereich + */ + public String ValidationReport_Report_ViewRegion; + + /** + * führende Örtlichkeit + */ + public String ValidationReport_Metadata_Location; + + /** + * führende Strecke + */ + public String ValidationReport_Metadata_Route; + + /** + * Bauzustand Kurzbezeichnung + */ + public String ValidationReport_Metadata_BuildDesignation; + + /** + * Index + */ + public String ValidationReport_Metadata_Index; + + /** + * Laufende Nummer + */ + public String ValidationReport_Metadata_LfdNr; + + /** + * Wesentliche Planungsmetadaten + */ + public String ValidationReport_Metadata; } diff --git a/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/parts/ModelInfoSection.java b/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/parts/ModelInfoSection.java deleted file mode 100644 index 25821ceab7..0000000000 --- a/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/parts/ModelInfoSection.java +++ /dev/null @@ -1,189 +0,0 @@ -/** - * Copyright (c) 2026 DB InfraGO AG and others - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v2.0 which is available at - * https://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - */ -package org.eclipse.set.feature.validation.parts; - -import java.util.Collection; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.eclipse.set.feature.validation.Messages; -import org.eclipse.set.model.validationreport.ValidationReport; -import org.eclipse.set.model.validationreport.VersionInfo; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.forms.widgets.ExpandableComposite; -import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.xtext.xbase.lib.Pair; - -/** - * The section control for loaded file information - * - * @author truong - */ -public class ModelInfoSection { - - protected class GroupSectionControl { - Composite viewSection; - Group group; - - public GroupSectionControl(final Composite viewSection, - final String groupName) { - this.viewSection = viewSection; - createGroup(groupName); - } - - private void createGroup(final String groupName) { - group = new Group(viewSection, SWT.NONE); - group.setText(groupName); - group.setLayout(new GridLayout(2, false)); - group.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - } - - public GroupSectionControl addTextControl(final String labelText, - final String text) { - final TextFieldWithLabelControl textFieldWithLabelControl = new TextFieldWithLabelControl( - group, labelText, text); - textFieldWithLabelControl.createControl(); - return this; - } - } - - protected record TextFieldWithLabelControl(Composite parent, - String labelText, String text) { - public void createControl() { - final Label label = new Label(parent, SWT.NONE); - label.setText(labelText); - - final Text textField = new Text(parent, SWT.BORDER); - textField.setLayoutData( - new GridData(SWT.FILL, SWT.CENTER, true, false)); - textField.setEnabled(false); - textField.setText(text); - } - } - - Messages messages; - Composite parent; - - /** - * @param parent - * the parent composite - * @param messages - * the {@link Messages} - */ - public ModelInfoSection(final Composite parent, final Messages messages) { - this.messages = messages; - this.parent = parent; - } - - protected void createModelInformationGroup( - final ValidationReport validationReport) { - final Composite section = createExpandedSecion( - messages.ValidationReport_ModelInfo); - - final GroupSectionControl loadedFileGroup = new GroupSectionControl( - section, messages.ValidationReport_GeladeneDatei); - loadedFileGroup // - .addTextControl( - messages.ValidationReport_GeladeneDatei_DateiName, - validationReport.getFileInfo().getFileName()) - .addTextControl( - messages.ValidationReport_GeladeneDatei_TimeStamp, - validationReport.getFileInfo().getTimeStamp()) - .addTextControl(messages.ValidationReport_GeladeneDatei_MD5, - validationReport.getFileInfo().getChecksum()) - .addTextControl(messages.ValidationReport_GeladeneDatei_GUID, - validationReport.getFileInfo().getGuid()); - - final GroupSectionControl validityGroup = new GroupSectionControl( - section, messages.ValidationReport_Validity); - validityGroup // - .addTextControl(messages.ValidationReport_Validity_XSD_VALID, - validationReport.getXsdValid()) - .addTextControl(messages.ValidationReport_Validity_EMF_VALID, - validationReport.getEmfValid()) - .addTextControl(messages.ValidationReport_Validity_ModelLoaded, - validationReport.getModelLoaded()); - - final Pair usedVersion = transformVersionInfo( - validationReport.getFileInfo().getUsedVersion()); - final GroupSectionControl loadedVersionGroup = new GroupSectionControl( - section, messages.ValidationReport_Used_Version); - loadedVersionGroup // - .addTextControl(messages.ValidationReport_Version_PlanPro, - usedVersion.getKey()) - .addTextControl( - messages.ValidationReport_Version_Signalbegriffe, - usedVersion.getValue()); - - final Pair supportedVersions = transformVersionInfo( - validationReport.getSupportedVersion()); - final GroupSectionControl supportVersionGroup = new GroupSectionControl( - section, messages.ValidationReport_Supported_Version); - supportVersionGroup // - .addTextControl(messages.ValidationReport_Version_PlanPro, - supportedVersions.getKey()) - .addTextControl( - messages.ValidationReport_Version_Signalbegriffe, - supportedVersions.getValue()); - } - - protected void createFunctionalInformationenGroup( - final ValidationReport validationReport) { - final Composite expandedSecion = createExpandedSecion( - messages.ValidationReport_FunctionalModelInfo); - final GroupSectionControl subworkGroup = new GroupSectionControl( - expandedSecion, messages.ValidationReport_Subworks); - subworkGroup.addTextControl( - messages.ValidationReport_Subwork_Model_Content, - validationReport.getSubworkTypes()); - - final GroupSectionControl containerContentsGroup = new GroupSectionControl( - expandedSecion, messages.ValidationReport_ContainerContents); - containerContentsGroup.addTextControl( - messages.ValidationReport_Subwork_Model_Content, - validationReport.getFileInfo().getContainerContents()); - } - - private Composite createExpandedSecion(final String sectionTitle) { - final Composite container = new Composite(parent, SWT.NONE); - container.setLayout(new FillLayout()); - container.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - final FormToolkit formToolkit = new FormToolkit(parent.getDisplay()); - final ExpandableComposite ec = formToolkit - .createExpandableComposite(container, - ExpandableComposite.TWISTIE - | ExpandableComposite.TITLE_BAR - | ExpandableComposite.EXPANDED); - ec.setBackground(parent.getBackground()); - ec.setText(sectionTitle); - final Composite section = new Composite(ec, SWT.NONE); - section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - section.setLayout(new GridLayout(2, true)); - ec.setClient(section); - return section; - } - - private static Pair transformVersionInfo( - final VersionInfo versionInfo) { - final Function, String> toString = versions -> versions - .stream() - .collect(Collectors.joining(", ")); //$NON-NLS-1$ - return new Pair<>(toString.apply(versionInfo.getPlanProVersions()), - toString.apply(versionInfo.getSignalbegriffeVersions())); - } -} diff --git a/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/parts/ValidationPart.java b/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/parts/ValidationPart.java index 6b3b6ca85c..dfb46d0987 100644 --- a/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/parts/ValidationPart.java +++ b/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/parts/ValidationPart.java @@ -12,11 +12,9 @@ import java.util.List; import org.eclipse.e4.core.services.nls.Translation; -import org.eclipse.e4.ui.di.UISynchronize; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.emf.common.notify.Notification; import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.set.basis.ProblemMessage; import org.eclipse.set.basis.cache.Cache; import org.eclipse.set.basis.constants.Events; @@ -25,7 +23,6 @@ import org.eclipse.set.basis.extensions.MApplicationElementExtensions; import org.eclipse.set.basis.files.ToolboxFileRole; import org.eclipse.set.core.services.cache.CacheService; -import org.eclipse.set.core.services.configurationservice.UserConfigurationService; import org.eclipse.set.core.services.dialog.DialogService; import org.eclipse.set.core.services.enumtranslation.EnumTranslationService; import org.eclipse.set.core.services.part.ToolboxPartService; @@ -37,24 +34,21 @@ import org.eclipse.set.model.validationreport.ValidationReport; import org.eclipse.set.model.validationreport.ValidationSeverity; import org.eclipse.set.utils.BasePart; -import org.eclipse.set.utils.Fonts; import org.eclipse.set.utils.SaveAndRefreshAction; import org.eclipse.set.utils.SelectableAction; import org.eclipse.set.utils.events.ContainerDataChanged; import org.eclipse.set.utils.events.ProjectDataChanged; -import org.eclipse.set.utils.table.menu.TableMenuService; import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; +import org.osgi.service.event.EventHandler; +import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.inject.Inject; @@ -66,26 +60,19 @@ */ public class ValidationPart extends BasePart { - private static final int BUTTON_WIDTH_EXPORT_VALIDATION = 30; - - private static final String VIEW_VALIDATION_REPORT = "validationReport"; //$NON-NLS-1$ + protected static final String VIEW_VALIDATION_REPORT = "validationReport"; //$NON-NLS-1$ private Exception createException; @Inject private ToolboxPartService toolboxPartService; - @Inject - private TableMenuService tableMenuService; - private SessionToValidationReportTransformation transformation; private ValidationReport validationReport; private ValidationTableView tableView; - private Button exportValidationButton; - @Inject private PlanProVersionService versionService; @@ -96,17 +83,25 @@ public class ValidationPart extends BasePart { @Translation Messages messages; - @Inject - UISynchronize sync; - @Inject CacheService cacheService; - @Inject - UserConfigurationService userConfigService; - private Listener resizeListener; private Composite resizeListenerObject; + private EventHandler subworkChangeHandler; + + private ValidationViewModelInfo validationView; + + @PostConstruct + void postConstrct() { + subworkChangeHandler = event -> { + if (!event.getTopic().equalsIgnoreCase(Events.SUBWORK_CHANGED)) { + return; + } + validationView.update(); + }; + getBroker().subscribe(Events.SUBWORK_CHANGED, subworkChangeHandler); + } /** * Create the part. @@ -140,29 +135,21 @@ protected void create(final Composite parent) { transformation = new SessionToValidationReportTransformation( messages, versionService, enumTranslationService); validationReport = transformation.transform(getModelSession()); - storageReport(); + final ScrolledComposite sc1 = new ScrolledComposite(parent, + SWT.V_SCROLL); + sc1.setLayout(new GridLayout()); + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc1); - // Register nattable injector - tableView = new ValidationTableView(this, messages, - tableMenuService); - - final ModelInfoSection validationView = new ModelInfoSection(parent, - messages); + validationView = new ValidationViewModelInfo(sc1, messages, + validationReport); - validationView.createModelInformationGroup(validationReport); - validationView.createFunctionalInformationenGroup(validationReport); - - createInjectedTable(parent); - // initial update of button states - updateButtonStates(); - - // Resize the EMF Forms view according to the outside area to - // update - // the scroll view size when the window is resized + validationView.createView(getModelSession(), toolboxPartService); + sc1.setContent(validationView); resizeListenerObject = parent; resizeListener = event -> { - final Point size = parent.computeSize(SWT.DEFAULT, SWT.DEFAULT); + final Point size = validationView.computeSize(SWT.DEFAULT, + SWT.DEFAULT); final Rectangle bounds = parent.getBounds(); // No offset from parent bounds.x = 0; @@ -172,7 +159,7 @@ protected void create(final Composite parent) { // Use internal height or the parent height bounds.height = (int) Math.max(bounds.height - 25.0, size.y * 0.9); - + validationView.setBounds(bounds); }; parent.addListener(SWT.Resize, resizeListener); @@ -182,65 +169,6 @@ protected void create(final Composite parent) { } } - protected Control createInjectedTable(final Composite innerParent) { - final Label validationReportLabel = new Label(innerParent, SWT.LEFT); - final Font font = localResourceManager.create(Fonts.TABLE_HEADING); - validationReportLabel.setFont(font); - validationReportLabel.setText(messages.ValidationReport_Report_Title); - - final Composite composite = new Composite(innerParent, SWT.NONE); - GridLayoutFactory.swtDefaults().numColumns(3).applyTo(composite); - GridDataFactory.swtDefaults() - .align(SWT.FILL, SWT.FILL) - .grab(true, false) - .applyTo(composite); - - final Control natTable = tableView.create(innerParent, - validationReport); - // create the open view button - final Button showTableButton = new Button(composite, SWT.PUSH); - GridDataFactory.swtDefaults() - .align(SWT.LEFT, SWT.FILL) - .grab(false, false) - .applyTo(showTableButton); - - showTableButton.setText(messages.ShowValidationTableMsg); - showTableButton.addListener(SWT.Selection, - event -> showValidationTable()); - showTableButton.setSize(BUTTON_WIDTH_EXPORT_VALIDATION, 0); - - // create the toggle collapsed button - final Button collapseAllButton = tableView - .createExpandCollapseAllButton(composite, - messages.ValidationTable_ExpandAllGroup, - messages.ValidationTable_CollapseAllGroup); - - exportValidationButton = new Button(composite, SWT.PUSH); - GridDataFactory.swtDefaults() - .align(SWT.RIGHT, SWT.FILL) - .grab(true, false) - .applyTo(exportValidationButton); - exportValidationButton.setText(messages.ExportValidationMsg); - exportValidationButton.addListener(SWT.Selection, - event -> tableView.exportCsv()); - exportValidationButton.setSize(BUTTON_WIDTH_EXPORT_VALIDATION, 0); - - // Setup layout - showTableButton - .setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, true)); - collapseAllButton - .setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, true)); - exportValidationButton - .setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, true, true)); - - GridDataFactory.swtDefaults() - .align(SWT.FILL, SWT.FILL) - .grab(true, true) - .hint(SWT.DEFAULT, 600) - .applyTo(natTable); - return natTable; - } - private void storageReport() { final Cache cache = cacheService.getCache(ToolboxFileRole.SESSION, ToolboxConstants.CacheId.PROBLEM_MESSAGE); @@ -266,10 +194,6 @@ private void storageReport() { getBroker().post(Events.PROBLEMS_CHANGED, null); } - void showValidationTable() { - toolboxPartService.showPart(ToolboxConstants.VALIDATION_TABLE_PART_ID); - } - @Override protected void updateViewContainerDataChanged( final List container) { @@ -293,19 +217,11 @@ private void updateValidationView() { // reset outdated mark setOutdated(false); - // update buttons - updateButtonStates(); - // update table tableView.updateView(validationReport); } } - private void updateButtonStates() { - exportValidationButton - .setEnabled(!validationReport.getProblems().isEmpty()); - } - @Override protected SelectableAction getOutdatedAction() { return new SaveAndRefreshAction(this); diff --git a/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/parts/ValidationViewModelInfo.java b/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/parts/ValidationViewModelInfo.java new file mode 100644 index 0000000000..63e61cc1bc --- /dev/null +++ b/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/parts/ValidationViewModelInfo.java @@ -0,0 +1,350 @@ +/** + * Copyright (c) 2026 DB InfraGO AG and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + */ +package org.eclipse.set.feature.validation.parts; + +import static org.eclipse.set.ppmodel.extensions.PlanProSchnittstelleExtensions.*; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.function.ToLongFunction; +import java.util.stream.Collectors; + +import javax.xml.datatype.XMLGregorianCalendar; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.jface.databinding.swt.typed.WidgetProperties; +import org.eclipse.set.basis.IModelSession; +import org.eclipse.set.basis.constants.ToolboxConstants; +import org.eclipse.set.basis.observable.SupplierObservableValue; +import org.eclipse.set.core.services.part.ToolboxPartService; +import org.eclipse.set.feature.validation.Messages; +import org.eclipse.set.model.planpro.PlanPro.PlanPro_Schnittstelle; +import org.eclipse.set.model.validationreport.ObjectScope; +import org.eclipse.set.model.validationreport.ValidationProblem; +import org.eclipse.set.model.validationreport.ValidationReport; +import org.eclipse.set.model.validationreport.ValidationSeverity; +import org.eclipse.set.model.validationreport.VersionInfo; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.widgets.ExpandableComposite; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.xtext.xbase.lib.Pair; + +/** + * The section control for loaded file information + * + * @author truong + */ +public class ValidationViewModelInfo extends Composite { + + protected class GroupSectionControl { + Composite viewSection; + Group group; + + public GroupSectionControl(final Composite viewSection, + final String groupName) { + this.viewSection = viewSection; + createGroup(groupName); + } + + private void createGroup(final String groupName) { + group = new Group(viewSection, SWT.NONE); + group.setText(groupName); + group.setLayout(new GridLayout(2, false)); + group.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + } + + public GroupSectionControl addTextControl(final String labelText, + final String text) { + final TextFieldWithLabelControl textFieldWithLabelControl = new TextFieldWithLabelControl( + group, labelText, text); + textFieldWithLabelControl.createControl(); + return this; + } + + public GroupSectionControl addObservableTextControl( + final String labelText, final Supplier getTextFunc) { + final Label label = new Label(group, SWT.NONE); + label.setText(labelText); + + final Text textField = new Text(group, SWT.BORDER); + textField.setLayoutData( + new GridData(SWT.FILL, SWT.CENTER, true, false)); + textField.setEnabled(false); + final SupplierObservableValue text = new SupplierObservableValue<>( + getTextFunc, String.class); + observableValues.add(text); + final DataBindingContext ctx = new DataBindingContext(); + ctx.bindValue(WidgetProperties.text().observe(textField), text); + return this; + } + } + + protected record TextFieldWithLabelControl(Composite parent, + String labelText, String text) { + public void createControl() { + final Label label = new Label(parent, SWT.NONE); + label.setText(labelText); + + final Text textField = new Text(parent, SWT.BORDER); + textField.setLayoutData( + new GridData(SWT.FILL, SWT.CENTER, true, false)); + textField.setEnabled(false); + textField.setText(text); + } + } + + protected Messages messages; + protected ValidationReport validationReport; + FormToolkit formToolkit; + private final List> observableValues; + + /** + * @param parent + * the parent composite + * @param messages + * the {@link Messages} + * @param validationReport + * the {@link ValidationReport} + */ + public ValidationViewModelInfo(final Composite parent, + final Messages messages, final ValidationReport validationReport) { + super(parent, SWT.NONE); + setLayout(new GridLayout()); + setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + formToolkit = new FormToolkit(getDisplay()); + this.messages = messages; + this.validationReport = validationReport; + this.observableValues = new ArrayList<>(); + } + + /** + * @param modelSession + * the {@link IModelSession} + * @param toolboxPartService + * the {@link ToolboxPartService} + */ + public void createView(final IModelSession modelSession, + final ToolboxPartService toolboxPartService) { + createModelInformationGroup(); + createFunctionalInformationenGroup(); + createMetadataInformationenGroup(modelSession); + createValidationReportOverviewGroup(toolboxPartService); + } + + private void createModelInformationGroup() { + final Composite section = createExpandedSecion( + messages.ValidationReport_ModelInfo); + + final GroupSectionControl loadedFileGroup = new GroupSectionControl( + section, messages.ValidationReport_GeladeneDatei); + loadedFileGroup // + .addTextControl( + messages.ValidationReport_GeladeneDatei_DateiName, + validationReport.getFileInfo().getFileName()) + .addTextControl( + messages.ValidationReport_GeladeneDatei_TimeStamp, + validationReport.getFileInfo().getTimeStamp()) + .addTextControl(messages.ValidationReport_GeladeneDatei_MD5, + validationReport.getFileInfo().getChecksum()) + .addTextControl(messages.ValidationReport_GeladeneDatei_GUID, + validationReport.getFileInfo().getGuid()); + + final GroupSectionControl validityGroup = new GroupSectionControl( + section, messages.ValidationReport_Validity); + validityGroup // + .addTextControl(messages.ValidationReport_Validity_XSD_VALID, + validationReport.getXsdValid()) + .addTextControl(messages.ValidationReport_Validity_EMF_VALID, + validationReport.getEmfValid()) + .addTextControl(messages.ValidationReport_Validity_ModelLoaded, + validationReport.getModelLoaded()); + + final Pair usedVersion = transformVersionInfo( + validationReport.getFileInfo().getUsedVersion()); + final GroupSectionControl loadedVersionGroup = new GroupSectionControl( + section, messages.ValidationReport_Used_Version); + loadedVersionGroup // + .addTextControl(messages.ValidationReport_Version_PlanPro, + usedVersion.getKey()) + .addTextControl( + messages.ValidationReport_Version_Signalbegriffe, + usedVersion.getValue()); + + final Pair supportedVersions = transformVersionInfo( + validationReport.getSupportedVersion()); + final GroupSectionControl supportVersionGroup = new GroupSectionControl( + section, messages.ValidationReport_Supported_Version); + supportVersionGroup // + .addTextControl(messages.ValidationReport_Version_PlanPro, + supportedVersions.getKey()) + .addTextControl( + messages.ValidationReport_Version_Signalbegriffe, + supportedVersions.getValue()); + } + + private void createFunctionalInformationenGroup() { + final Composite expandedSecion = createExpandedSecion( + messages.ValidationReport_FunctionalModelInfo); + final GroupSectionControl subworkGroup = new GroupSectionControl( + expandedSecion, messages.ValidationReport_Subworks); + subworkGroup.addTextControl( + messages.ValidationReport_Subwork_Model_Content, + validationReport.getSubworkTypes()); + + final GroupSectionControl containerContentsGroup = new GroupSectionControl( + expandedSecion, messages.ValidationReport_ContainerContents); + containerContentsGroup.addTextControl( + messages.ValidationReport_Subwork_Model_Content, + validationReport.getFileInfo().getContainerContents()); + } + + @SuppressWarnings("nls") + private void createMetadataInformationenGroup( + final IModelSession modelSession) { + final Composite expandedSecion = createExpandedSecion( + messages.ValidationReport_Metadata); + final PlanPro_Schnittstelle planProSchnittstelle = modelSession + .getPlanProSchnittstelle(); + final GroupSectionControl groupSectionControl = new GroupSectionControl( + expandedSecion, ""); + + groupSectionControl + .addObservableTextControl( + messages.ValidationReport_Metadata_Location, + () -> getFuehrendeOertlichkeit(planProSchnittstelle) + .orElse("")) + .addObservableTextControl( + messages.ValidationReport_Metadata_Route, + () -> getStreckeAbschnitt(planProSchnittstelle) + .orElse("")) + .addObservableTextControl( + messages.ValidationReport_Metadata_BuildDesignation, + () -> getBauzustandKurzbezeichnung(planProSchnittstelle) + .orElse("")); + + final GroupSectionControl secondGroup = new GroupSectionControl( + expandedSecion, ""); + secondGroup + .addObservableTextControl( + messages.ValidationReport_Metadata_Index, + () -> getIndexAusgabe(planProSchnittstelle).orElse("")) + .addObservableTextControl( + messages.ValidationReport_Metadata_LfdNr, + () -> getLaufendeNummerAusgabe(planProSchnittstelle) + .orElse("")) + .addObservableTextControl( + messages.ValidationReport_GeladeneDatei_TimeStamp, + () -> { + final Optional datumAbschlussGruppe = getDatumAbschlussGruppe( + planProSchnittstelle); + return datumAbschlussGruppe.isPresent() // + ? datumAbschlussGruppe.get().toString() // + : ""; + }); + } + + private void createValidationReportOverviewGroup( + final ToolboxPartService toolboxPartService) { + final Composite expandedSecion = createExpandedSecion( + messages.ValidationReport_Report_Title); + createReportInfoGroup(expandedSecion, + messages.ValidationReport_Report_PlaningRegion, + ObjectScope.PLAN); + + createReportInfoGroup(expandedSecion, + messages.ValidationReport_Report_ViewRegion, + ObjectScope.BETRACHTUNG); + + final Button showTableButton = new Button(expandedSecion, SWT.PUSH); + showTableButton.setText(messages.ShowValidationTableMsg); + showTableButton.addListener(SWT.Selection, event -> toolboxPartService + .showPart(ToolboxConstants.VALIDATION_TABLE_PART_ID)); + showTableButton + .setLayoutData(new GridData(SWT.LEFT, SWT.FILL, true, true)); + + } + + private void createReportInfoGroup(final Composite expandedSection, + final String groupTitle, final ObjectScope scope) { + final List reportInRegion = validationReport + .getProblems() + .stream() + .filter(report -> report.getObjectScope().equals(scope)) + .toList(); + final ToLongFunction getSeverityCount = severity -> reportInRegion + .stream() + .filter(report -> report.getSeverity().equals(severity)) + .count(); + + final GroupSectionControl regionGroup = new GroupSectionControl( + expandedSection, groupTitle); + + final long errorCount = getSeverityCount + .applyAsLong(ValidationSeverity.ERROR); + regionGroup.addTextControl(messages.ErrorMsg, + String.valueOf(errorCount)); + + final long warningCount = getSeverityCount + .applyAsLong(ValidationSeverity.WARNING); + regionGroup.addTextControl(messages.WarningMsg, + String.valueOf(warningCount)); + + final long successCount = getSeverityCount + .applyAsLong(ValidationSeverity.SUCCESS); + regionGroup.addTextControl(messages.SuccessMsg, + String.valueOf(successCount)); + } + + private Composite createExpandedSecion(final String sectionTitle) { + final Composite container = new Composite(this, SWT.NONE); + container.setLayout(new FillLayout()); + container.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + final ExpandableComposite ec = formToolkit + .createExpandableComposite(container, + ExpandableComposite.TWISTIE + | ExpandableComposite.TITLE_BAR + | ExpandableComposite.EXPANDED); + ec.setBackground(getBackground()); + ec.setText(sectionTitle); + final Composite section = new Composite(ec, SWT.NONE); + section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + section.setLayout(new GridLayout(2, true)); + ec.setClient(section); + return section; + } + + private static Pair transformVersionInfo( + final VersionInfo versionInfo) { + final Function, String> toString = versions -> versions + .stream() + .collect(Collectors.joining(", ")); //$NON-NLS-1$ + return new Pair<>(toString.apply(versionInfo.getPlanProVersions()), + toString.apply(versionInfo.getSignalbegriffeVersions())); + } + + @Override + public void update() { + super.update(); + observableValues.forEach(SupplierObservableValue::calculate); + } +} diff --git a/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/report/SessionToValidationReportTransformation.xtend b/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/report/SessionToValidationReportTransformation.xtend index 669bd6f196..fce3e12151 100644 --- a/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/report/SessionToValidationReportTransformation.xtend +++ b/java/bundles/org.eclipse.set.feature.validation/src/org/eclipse/set/feature/validation/report/SessionToValidationReportTransformation.xtend @@ -332,7 +332,7 @@ class SessionToValidationReportTransformation { if (objectScope === null || objectScope === ObjectScope.UNKNOWN) { if (validationSourceClass == PlanPro_Layoutinfo || - type === LayoutInfoRequired.LAYOUT_VALIDATION_TYPE) { + type === LayoutInfoRequired.METADATA_VALIDATION_TYPE) { objectScope = ObjectScope.LAYOUT } else { objectScope = ObjectScope.CONTENT diff --git a/java/bundles/org.eclipse.set.swtbot/src/org/eclipse/set/swtbot/ValidationViewTest.java b/java/bundles/org.eclipse.set.swtbot/src/org/eclipse/set/swtbot/ValidationViewTest.java index 1af114a281..9672fd4a17 100644 --- a/java/bundles/org.eclipse.set.swtbot/src/org/eclipse/set/swtbot/ValidationViewTest.java +++ b/java/bundles/org.eclipse.set.swtbot/src/org/eclipse/set/swtbot/ValidationViewTest.java @@ -29,6 +29,8 @@ import org.eclipse.set.swtbot.utils.AbstractSWTBotTest; import org.eclipse.set.swtbot.utils.SWTBotUtils; import org.eclipse.set.utils.table.export.ExportToCSV; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotCTabItem; import org.eclipse.swtbot.swt.finder.widgets.SWTBotText; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -209,6 +211,13 @@ protected void thenExpectModelInformationEquals() { } protected void whenOpeningValidateView() { + final SWTBotCTabItem cTabItem = bot.cTabItem("Validierung"); + cTabItem.activate(); + } + + protected void whenOpenReportTable() { + whenOpeningValidateView(); + bot.button("Zeige Meldungen").click(); nattableBot = SWTBotUtils.waitForNattable(bot, 30000); layers = SWTBotUtils.getNattableLayers(nattableBot); } @@ -223,8 +232,11 @@ void beforeAll() throws Exception { @ExtendWith(TestFailHandle.class) void testValidateReport() throws Exception { givenReferenceCSV(); - whenOpeningValidateView(); - bot.button("Alle ausklappen").click(); + whenOpenReportTable(); + final SWTBotButton ausKlappenButton = bot.button("Alle ausklappen"); + if (ausKlappenButton != null) { + ausKlappenButton.click(); + } thenRowAndColumnCountEqualReferenceCSV(); thenExpectTableDataEqualReferenceCSV(); }