diff --git a/java/bundles/org.eclipse.set.feature.plazmodel/META-INF/MANIFEST.MF b/java/bundles/org.eclipse.set.feature.plazmodel/META-INF/MANIFEST.MF index 98f3932e05..fec3b3ffcb 100644 --- a/java/bundles/org.eclipse.set.feature.plazmodel/META-INF/MANIFEST.MF +++ b/java/bundles/org.eclipse.set.feature.plazmodel/META-INF/MANIFEST.MF @@ -104,6 +104,7 @@ Service-Component: OSGI-INF/org.eclipse.set.feature.plazmodel.PlazModelDescripti OSGI-INF/org.eclipse.set.feature.plazmodel.check.TeilbereichTOPKanteLength.xml, OSGI-INF/org.eclipse.set.feature.plazmodel.check.TeilbereicheUnique.xml, OSGI-INF/org.eclipse.set.feature.plazmodel.check.TopGeoCoverage.xml, + OSGI-INF/org.eclipse.set.feature.plazmodel.check.UnicodeCharactersValid.xml, OSGI-INF/org.eclipse.set.feature.plazmodel.check.UniqueTopKanteBereichObject.xml, OSGI-INF/org.eclipse.set.feature.plazmodel.check.UnusedBearbeitungsvermerke.xml, OSGI-INF/org.eclipse.set.feature.plazmodel.export.ExportTopologicalCoordinateDescriptionService.xml, diff --git a/java/bundles/org.eclipse.set.feature.plazmodel/src/org/eclipse/set/feature/plazmodel/check/UnicodeCharactersValid.java b/java/bundles/org.eclipse.set.feature.plazmodel/src/org/eclipse/set/feature/plazmodel/check/UnicodeCharactersValid.java new file mode 100644 index 0000000000..7e45661305 --- /dev/null +++ b/java/bundles/org.eclipse.set.feature.plazmodel/src/org/eclipse/set/feature/plazmodel/check/UnicodeCharactersValid.java @@ -0,0 +1,124 @@ +/** + * 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.plazmodel.check; + +import java.awt.Font; +import java.awt.FontFormatException; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.set.basis.IModelSession; +import org.eclipse.set.basis.Pair; +import org.eclipse.set.core.services.font.FontService; +import org.eclipse.set.core.services.font.FontService.FopFont; +import org.eclipse.set.model.plazmodel.PlazError; +import org.eclipse.set.model.plazmodel.PlazFactory; +import org.eclipse.set.model.validationreport.ValidationSeverity; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +import com.google.common.collect.Streams; + +/** + * Valid the String-Value, whether contain illegal characters or not + * + * @author truong + */ +@Component +public class UnicodeCharactersValid implements PlazCheck { + + @Reference + FontService fontService; + + @Override + public List run(final IModelSession modelSession) { + try { + final List fopFonts = new ArrayList<>(); + for (final FopFont font : fontService.getFopFonts()) { + fopFonts.add(Font.createFont(Font.TRUETYPE_FONT, + font.path().toFile())); + } + final List> wertObjects = Streams + .stream(modelSession.getPlanProSchnittstelle() + .eAllContents()) + .map(UnicodeCharactersValid::getObjectWithValue) + .filter(pair -> pair != null && pair.getSecond() != null + && !pair.getSecond().isEmpty()) + .toList(); + + return wertObjects.stream() + .filter(pair -> !isValidStringValue(pair.getSecond(), + fopFonts)) + .map(pair -> createError(pair.getFirst(), pair.getSecond())) + .toList(); + } catch (IOException | FontFormatException e) { + return List.of(createFontError(e)); + } + } + + private static Pair getObjectWithValue(final EObject obj) { + try { + final Method getWertMethod = obj.getClass() + .getDeclaredMethod("getWert"); //$NON-NLS-1$ + if (getWertMethod == null || !getWertMethod.getReturnType() + .isAssignableFrom(String.class)) { + return null; + } + + return new Pair<>(obj, (String) getWertMethod.invoke(obj)); + } catch (final Exception e) { + return null; + } + } + + private static boolean isValidStringValue(final String value, + final List availableFonts) { + return availableFonts.stream() + .anyMatch(font -> value.chars() + .allMatch(chInt -> font.canDisplay(chInt))); + } + + private PlazError createError(final EObject obj, final String value) { + final PlazError plazError = PlazFactory.eINSTANCE.createPlazError(); + plazError.setType(checkType()); + plazError.setSeverity(ValidationSeverity.ERROR); + plazError.setObject(obj); + plazError.setMessage(String + .format("Der Wert: %s enthält ungültig sonderzeichen", value)); //$NON-NLS-1$ + return plazError; + } + + @Override + public String checkType() { + return "Sonderzeichen"; //$NON-NLS-1$ + } + + @Override + public String getDescription() { + return "Es gibt keine ungültigen Sonderzeichen"; //$NON-NLS-1$ + } + + @Override + public String getGeneralErrMsg() { + return "Es gibt Objekte mit ungültigen Sonderzeichen"; //$NON-NLS-1$ + } + + private PlazError createFontError(final Exception e) { + final PlazError plazError = PlazFactory.eINSTANCE.createPlazError(); + plazError.setType(checkType()); + plazError.setSeverity(ValidationSeverity.ERROR); + plazError.setMessage("Can't load fop fonts: " + e.getMessage()); //$NON-NLS-1$ + return plazError; + } +} diff --git a/java/bundles/org.eclipse.set.swtbot/.classpath b/java/bundles/org.eclipse.set.swtbot/.classpath index 2be21a9d32..6568b320d9 100644 --- a/java/bundles/org.eclipse.set.swtbot/.classpath +++ b/java/bundles/org.eclipse.set.swtbot/.classpath @@ -2,6 +2,7 @@ + diff --git a/java/bundles/org.eclipse.set.swtbot/META-INF/MANIFEST.MF b/java/bundles/org.eclipse.set.swtbot/META-INF/MANIFEST.MF index 6f9ff24e4d..126539e258 100644 --- a/java/bundles/org.eclipse.set.swtbot/META-INF/MANIFEST.MF +++ b/java/bundles/org.eclipse.set.swtbot/META-INF/MANIFEST.MF @@ -52,5 +52,7 @@ Bundle-ActivationPolicy: lazy Bundle-ClassPath: ., test_res/table_reference/, test_res/test_file/, + test_res/test_font/ test_res/ -Service-Component: OSGI-INF/org.eclipse.set.swtbot.utils.MockDialogServiceContextFunction.xml +Service-Component: OSGI-INF/org.eclipse.set.swtbot.utils.MockDialogServiceContextFunction.xml, + OSGI-INF/org.eclipse.set.swtbot.utils.MockFontService.xml diff --git a/java/bundles/org.eclipse.set.swtbot/OSGI-INF/org.eclipse.set.swtbot.utils.MockFontService.xml b/java/bundles/org.eclipse.set.swtbot/OSGI-INF/org.eclipse.set.swtbot.utils.MockFontService.xml new file mode 100644 index 0000000000..471b7c3fa2 --- /dev/null +++ b/java/bundles/org.eclipse.set.swtbot/OSGI-INF/org.eclipse.set.swtbot.utils.MockFontService.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/java/bundles/org.eclipse.set.swtbot/build.properties b/java/bundles/org.eclipse.set.swtbot/build.properties index 65d4e55883..0d48ccebc1 100644 --- a/java/bundles/org.eclipse.set.swtbot/build.properties +++ b/java/bundles/org.eclipse.set.swtbot/build.properties @@ -4,6 +4,7 @@ bin.includes = META-INF/,\ test_res/,\ .,\ test_res/table_reference/,\ - test_res/test_file/ + test_res/test_file/, \ + test_res/test_font/ source.. = src/ src.includes = test_res/ diff --git a/java/bundles/org.eclipse.set.swtbot/src/org/eclipse/set/swtbot/utils/AbstractSWTBotTest.java b/java/bundles/org.eclipse.set.swtbot/src/org/eclipse/set/swtbot/utils/AbstractSWTBotTest.java index 67f4b2983f..61a0dce425 100644 --- a/java/bundles/org.eclipse.set.swtbot/src/org/eclipse/set/swtbot/utils/AbstractSWTBotTest.java +++ b/java/bundles/org.eclipse.set.swtbot/src/org/eclipse/set/swtbot/utils/AbstractSWTBotTest.java @@ -14,8 +14,12 @@ import java.io.InputStream; import java.net.URL; import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; +import org.eclipse.set.core.services.font.FontService.FopFont; import org.eclipse.swtbot.swt.finder.SWTBot; import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; import org.junit.jupiter.api.BeforeEach; @@ -39,8 +43,12 @@ public void beforeEach() throws Exception { dialogService = getDialogService(); dialogService.openFileDialogHandler = filters -> Optional .of(getFilePath(getTestFile().getFullName())); + MockFontService.getFopFontsHandler = () -> loadTestFonts( + defaultTestFonts()); } + public abstract TestFile getTestFile(); + /** * Call execute test class to get test resource location * @@ -54,7 +62,15 @@ public Class getTestResourceClass() { return getClass(); } - public abstract TestFile getTestFile(); + protected Iterable defaultTestFonts() { + return List.of( // + new FopFont(Paths.get( + "test_res/test_font/Open_Sans_Condensed/OpenSans-CondLight.ttf"), + "Open Sans Condensed", "normal", "normal"), + new FopFont(Paths.get( + "test_res/test_font/Open_Sans_Condensed/OpenSans-CondBold.ttf"), + "Open Sans Condensed", "bold", "normal")); + } protected MockDialogService getDialogService() { return MockDialogServiceContextFunction.mockService; @@ -92,4 +108,31 @@ protected File getTestFileLocation(final String fileName) { .getLocation(); return new File(projectLocation.getPath() + fileName); } + + protected Iterable loadTestFonts( + final Iterable testFont) { + final List fonts = new ArrayList<>(); + for (final FopFont font : testFont) { + final File testFontFile = getTestFileLocation( + font.path().toString()); + if (!testFontFile.exists()) { + if (!testFontFile.getParentFile().exists()) { + testFontFile.getParentFile().mkdirs(); + } + try (final InputStream inputStream = getTestResourceClass() + .getClassLoader() + .getResourceAsStream(font.path().toString()); + FileOutputStream outputStream = new FileOutputStream( + testFontFile)) { + outputStream.write(inputStream.readAllBytes()); + } catch (final IOException e) { + throw new RuntimeException(e.getMessage()); + } + } + + fonts.add(new FopFont(Paths.get(testFontFile.getAbsolutePath()), + font.name(), font.weight(), font.style())); + } + return fonts; + } } diff --git a/java/bundles/org.eclipse.set.swtbot/src/org/eclipse/set/swtbot/utils/MockFontService.java b/java/bundles/org.eclipse.set.swtbot/src/org/eclipse/set/swtbot/utils/MockFontService.java new file mode 100644 index 0000000000..b28b15023b --- /dev/null +++ b/java/bundles/org.eclipse.set.swtbot/src/org/eclipse/set/swtbot/utils/MockFontService.java @@ -0,0 +1,30 @@ +/** + * 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.swtbot.utils; + +import java.util.function.Supplier; + +import org.eclipse.set.core.services.font.FontService; +import org.osgi.service.component.annotations.Component; + +/** + * + */ +@Component(property = "service.ranking:Integer=100") +public class MockFontService implements FontService { + public static Supplier> getFopFontsHandler; + + @Override + public Iterable getFopFonts() { + return getFopFontsHandler.get(); + } + +} diff --git a/java/bundles/org.eclipse.set.swtbot/test_res/table_reference/pphn_1_10_0_3/plaz_model_reference.csv b/java/bundles/org.eclipse.set.swtbot/test_res/table_reference/pphn_1_10_0_3/plaz_model_reference.csv index 6b62a65c74..6513a0593a 100644 --- a/java/bundles/org.eclipse.set.swtbot/test_res/table_reference/pphn_1_10_0_3/plaz_model_reference.csv +++ b/java/bundles/org.eclipse.set.swtbot/test_res/table_reference/pphn_1_10_0_3/plaz_model_reference.csv @@ -1,6 +1,6 @@ PlaZ Modell-Prüfung Datei: plaz_model_current.csv -Prüfungszeit: 2026-04-21 12:28:21 +Prüfungszeit: 2026-07-22 13:54:10 Werkzeugkofferversion: ${application-version} @@ -704,8 +704,9 @@ Werkzeugkofferversion: ${application-version} "679";"Erfolg";"Mehrfache Teilbereiche";"";"";"";"Fachdaten";"";"Teilbereichsgrenzen der LST-Objekte sind einzigartig." "680";"Erfolg";"Punktobjektabstand";"";"";"";"Fachdaten";"";"Der Punktobjektabstand aller LST-Objekte ist gültig." "681";"Erfolg";"Signalbefestigungsketten";"";"";"";"Fachdaten";"";"Die Verweisketten der Signalbefestigungen sind pausibel" -"682";"Erfolg";"TOP_Kante";"";"";"";"Fachdaten";"";"TOP_Kanten haben eindeutige Endknoten." -"683";"Erfolg";"TOP_Kante";"";"";"";"Fachdaten";"";"TOP_Kanten und GEO_Kanten haben übereinstimmende Längen." -"684";"Erfolg";"Untergewerk Art";"";"";"";"Fachdaten";"";"Jedes Untergewerk ist eindeutig und passt zu der zugehörigen Planung_Gruppe" -"685";"Erfolg";"Überhöhungslinie";"";"";"";"Fachdaten";"";"Topologische Pfade konnten für Überhöhungslinien gefunden werden." -"686";"Erfolg";"Überlappende Teilbereiche";"";"";"";"Fachdaten";"";"Teilbereichsgrenzen der LST-Objekte sind plausibel" +"682";"Erfolg";"Sonderzeichen";"";"";"";"Fachdaten";"";"Es gibt keine ungültigen Sonderzeichen" +"683";"Erfolg";"TOP_Kante";"";"";"";"Fachdaten";"";"TOP_Kanten haben eindeutige Endknoten." +"684";"Erfolg";"TOP_Kante";"";"";"";"Fachdaten";"";"TOP_Kanten und GEO_Kanten haben übereinstimmende Längen." +"685";"Erfolg";"Untergewerk Art";"";"";"";"Fachdaten";"";"Jedes Untergewerk ist eindeutig und passt zu der zugehörigen Planung_Gruppe" +"686";"Erfolg";"Überhöhungslinie";"";"";"";"Fachdaten";"";"Topologische Pfade konnten für Überhöhungslinien gefunden werden." +"687";"Erfolg";"Überlappende Teilbereiche";"";"";"";"Fachdaten";"";"Teilbereichsgrenzen der LST-Objekte sind plausibel" diff --git a/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/LICENSE.txt b/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/LICENSE.txt new file mode 100644 index 0000000000..57eeaca60a --- /dev/null +++ b/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/OpenSans-CondBold.ttf b/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/OpenSans-CondBold.ttf new file mode 100644 index 0000000000..4916dca3b8 Binary files /dev/null and b/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/OpenSans-CondBold.ttf differ diff --git a/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/OpenSans-CondLight.ttf b/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/OpenSans-CondLight.ttf new file mode 100644 index 0000000000..6c36358253 Binary files /dev/null and b/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/OpenSans-CondLight.ttf differ diff --git a/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/OpenSans-CondLightItalic.ttf b/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/OpenSans-CondLightItalic.ttf new file mode 100644 index 0000000000..ac38c7b922 Binary files /dev/null and b/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/OpenSans-CondLightItalic.ttf differ diff --git a/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/opensans.deps b/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/opensans.deps new file mode 100644 index 0000000000..a1aa5bcb7a --- /dev/null +++ b/java/bundles/org.eclipse.set.swtbot/test_res/test_font/Open_Sans_Condensed/opensans.deps @@ -0,0 +1 @@ +git/github/googlefonts/opensans/ebedbda589fe5bd861b02325aca98c86ad845251 \ No newline at end of file