From 5f9cbd2945402b27a5ed1677b13006acf9329a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Tue, 21 Jan 2025 16:52:22 +0100 Subject: [PATCH 1/8] #972: add CustomToolJsonDeserializer to prevent jackson error (#974) --- .../devonfw/tools/ide/json/JsonMapping.java | 10 +++ .../tools/ide/repo/CustomToolJson.java | 19 ++++- .../ide/repo/CustomToolJsonDeserializer.java | 71 +++++++++++++++++++ .../ide/repo/CustomToolJsonSerializer.java | 37 ++++++++++ .../tools/ide/repo/CustomToolsJson.java | 6 ++ .../ide/repo/CustomToolsJsonDeserializer.java | 56 +++++++++++++++ .../ide/repo/CustomToolsJsonSerializer.java | 34 +++++++++ 7 files changed, 230 insertions(+), 3 deletions(-) create mode 100644 cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonDeserializer.java create mode 100644 cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonSerializer.java create mode 100644 cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonDeserializer.java create mode 100644 cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonSerializer.java diff --git a/cli/src/main/java/com/devonfw/tools/ide/json/JsonMapping.java b/cli/src/main/java/com/devonfw/tools/ide/json/JsonMapping.java index deac9067b..9756c680a 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/json/JsonMapping.java +++ b/cli/src/main/java/com/devonfw/tools/ide/json/JsonMapping.java @@ -1,5 +1,11 @@ package com.devonfw.tools.ide.json; +import com.devonfw.tools.ide.repo.CustomToolJson; +import com.devonfw.tools.ide.repo.CustomToolJsonDeserializer; +import com.devonfw.tools.ide.repo.CustomToolJsonSerializer; +import com.devonfw.tools.ide.repo.CustomToolsJson; +import com.devonfw.tools.ide.repo.CustomToolsJsonDeserializer; +import com.devonfw.tools.ide.repo.CustomToolsJsonSerializer; import com.devonfw.tools.ide.url.model.file.json.ToolDependency; import com.devonfw.tools.ide.version.VersionIdentifier; import com.devonfw.tools.ide.version.VersionRange; @@ -30,6 +36,10 @@ public static ObjectMapper create() { customModule.addDeserializer(VersionIdentifier.class, new VersionIdentifierDeserializer()); customModule.addDeserializer(VersionRange.class, new VersionRangeDeserializer()); customModule.addDeserializer(ToolDependency.class, new ToolDependencyDeserializer()); + customModule.addDeserializer(CustomToolJson.class, new CustomToolJsonDeserializer()); + customModule.addDeserializer(CustomToolsJson.class, new CustomToolsJsonDeserializer()); + customModule.addSerializer(CustomToolJson.class, new CustomToolJsonSerializer()); + customModule.addSerializer(CustomToolsJson.class, new CustomToolsJsonSerializer()); customModule.addKeyDeserializer(VersionRange.class, new VersionRangeKeyDeserializer()); mapper = mapper.registerModule(customModule); return mapper; diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJson.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJson.java index 6bbe9ebc1..92503e962 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJson.java +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJson.java @@ -1,7 +1,6 @@ package com.devonfw.tools.ide.repo; import com.devonfw.tools.ide.os.OperatingSystem; -import com.fasterxml.jackson.annotation.JsonProperty; /** * JSON representation of a single {@link CustomToolMetadata}. @@ -13,8 +12,22 @@ * @param url the overridden {@link CustomToolsJson#url() repository URL} or {@code null} to inherit. * @see CustomToolsJson#tools() */ -public record CustomToolJson(String name, String version, @JsonProperty(value = "os-agnostic") boolean osAgnostic, - @JsonProperty(value = "arch-agnostic") boolean archAgnostic, String url) { +public record CustomToolJson(String name, String version, boolean osAgnostic, boolean archAgnostic, String url) { + + /** JSON property name for {@link #name()}. */ + public static final String PROPERTY_NAME = "name"; + + /** JSON property name for {@link #version()}. */ + public static final String PROPERTY_VERSION = "version"; + + /** JSON property name for {@link #osAgnostic()}. */ + public static final String PROPERTY_OS_AGNOSTIC = "os-agnostic"; + + /** JSON property name for {@link #archAgnostic()}. */ + public static final String PROPERTY_ARCH_AGNOSTIC = "arch-agnostic"; + + /** JSON property name for {@link #url()}. */ + public static final String PROPERTY_URL = "url"; /** * @return a new {@link CustomToolsJson} having {@link #url()} set to {@code null}. diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonDeserializer.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonDeserializer.java new file mode 100644 index 000000000..ee159b20f --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonDeserializer.java @@ -0,0 +1,71 @@ +package com.devonfw.tools.ide.repo; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +/** + * {@link JsonDeserializer} for {@link CustomToolJson}. + */ +public class CustomToolJsonDeserializer extends JsonDeserializer { + + private static final String INVALID_CUSTOM_TOOL = "Invalid JSON for custom tool!"; + + @Override + public CustomToolJson deserialize(JsonParser p, DeserializationContext context) throws IOException { + + JsonToken token = p.getCurrentToken(); + if (token == JsonToken.START_OBJECT) { + token = p.nextToken(); + String name = null; + String version = null; + boolean osAgnostic = true; + boolean archAgnostic = true; + String url = null; + while (token == JsonToken.FIELD_NAME) { + String property = p.currentName(); + if (property.equals(CustomToolJson.PROPERTY_NAME)) { + token = p.nextToken(); + assert token == JsonToken.VALUE_STRING; + name = p.getValueAsString(); + } else if (property.equals(CustomToolJson.PROPERTY_VERSION)) { + token = p.nextToken(); + assert token == JsonToken.VALUE_STRING; + version = p.getValueAsString(); + } else if (property.equals(CustomToolJson.PROPERTY_OS_AGNOSTIC)) { + token = p.nextToken(); + osAgnostic = parseBoolean(token, CustomToolJson.PROPERTY_OS_AGNOSTIC); + } else if (property.equals(CustomToolJson.PROPERTY_ARCH_AGNOSTIC)) { + token = p.nextToken(); + archAgnostic = parseBoolean(token, CustomToolJson.PROPERTY_ARCH_AGNOSTIC); + } else if (property.equals(CustomToolJson.PROPERTY_URL)) { + token = p.nextToken(); + assert token == JsonToken.VALUE_STRING; + url = p.getValueAsString(); + } else { + // ignore unknown property + // currently cannot log here due to https://github.com/devonfw/IDEasy/issues/404 + } + token = p.nextToken(); + } + if ((name != null) && (version != null)) { + return new CustomToolJson(name, version, osAgnostic, archAgnostic, url); + } + } + throw new IllegalStateException(INVALID_CUSTOM_TOOL); + } + + private boolean parseBoolean(JsonToken token, String name) { + if (token == JsonToken.VALUE_TRUE) { + return true; + } else if (token == JsonToken.VALUE_FALSE) { + return false; + } else { + throw new IllegalStateException(INVALID_CUSTOM_TOOL + " Property " + name + " must have boolean value (true or false)."); + } + } + +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonSerializer.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonSerializer.java new file mode 100644 index 000000000..56b83f140 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolJsonSerializer.java @@ -0,0 +1,37 @@ +package com.devonfw.tools.ide.repo; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +/** + * {@link JsonDeserializer} for {@link CustomToolJson}. + */ +public class CustomToolJsonSerializer extends JsonSerializer { + + @Override + public void serialize(CustomToolJson customToolJson, JsonGenerator jgen, SerializerProvider serializerProvider) throws IOException { + if (customToolJson == null) { + return; + } + jgen.writeStartObject(); + jgen.writeFieldName(CustomToolJson.PROPERTY_NAME); + jgen.writeString(customToolJson.name()); + jgen.writeFieldName(CustomToolJson.PROPERTY_VERSION); + jgen.writeString(customToolJson.version()); + jgen.writeFieldName(CustomToolJson.PROPERTY_OS_AGNOSTIC); + jgen.writeBoolean(customToolJson.osAgnostic()); + jgen.writeFieldName(CustomToolJson.PROPERTY_ARCH_AGNOSTIC); + jgen.writeBoolean(customToolJson.archAgnostic()); + String url = customToolJson.url(); + if ((url != null) && !url.isBlank()) { + jgen.writeFieldName(CustomToolJson.PROPERTY_URL); + jgen.writeString(url); + } + jgen.writeEndObject(); + } + +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJson.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJson.java index 7f8a8b19d..9789ce773 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJson.java +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJson.java @@ -11,4 +11,10 @@ */ public record CustomToolsJson(String url, List tools) { + /** JSON property name for {@link #url()}. */ + public static final String PROPERTY_URL = "url"; + + /** JSON property name for {@link #tools()}. */ + public static final String PROPERTY_TOOLS = "tools"; + } diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonDeserializer.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonDeserializer.java new file mode 100644 index 000000000..ee6ba4725 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonDeserializer.java @@ -0,0 +1,56 @@ +package com.devonfw.tools.ide.repo; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +/** + * {@link JsonDeserializer} for {@link CustomToolsJson}. + */ +public class CustomToolsJsonDeserializer extends JsonDeserializer { + + private static final String INVALID_CUSTOM_TOOLS = "Invalid JSON for custom tools!"; + + @Override + public CustomToolsJson deserialize(JsonParser p, DeserializationContext context) throws IOException { + + JsonToken token = p.getCurrentToken(); + if (token == JsonToken.START_OBJECT) { + token = p.nextToken(); + String url = null; + List tools = new ArrayList<>(); + while (token == JsonToken.FIELD_NAME) { + String property = p.currentName(); + if (property.equals(CustomToolsJson.PROPERTY_URL)) { + token = p.nextToken(); + assert token == JsonToken.VALUE_STRING; + url = p.getValueAsString(); + } else if (property.equals(CustomToolsJson.PROPERTY_TOOLS)) { + token = p.nextToken(); + if (token == JsonToken.START_ARRAY) { + token = p.nextToken(); + while (token != JsonToken.END_ARRAY) { + CustomToolJson customToolJson = p.readValueAs(CustomToolJson.class); + tools.add(customToolJson); + token = p.nextToken(); + } + } + } else { + // ignore unknown property + // currently cannot log here due to https://github.com/devonfw/IDEasy/issues/404 + } + token = p.nextToken(); + } + if ((url != null) && !tools.isEmpty()) { + return new CustomToolsJson(url, tools); + } + } + throw new IllegalStateException(INVALID_CUSTOM_TOOLS); + } + +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonSerializer.java b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonSerializer.java new file mode 100644 index 000000000..1a77794c9 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/repo/CustomToolsJsonSerializer.java @@ -0,0 +1,34 @@ +package com.devonfw.tools.ide.repo; + +import java.io.IOException; +import java.util.List; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +/** + * {@link JsonDeserializer} for {@link CustomToolsJson}. + */ +public class CustomToolsJsonSerializer extends JsonSerializer { + + @Override + public void serialize(CustomToolsJson customToolsJson, JsonGenerator jgen, SerializerProvider serializerProvider) throws IOException { + if (customToolsJson == null) { + return; + } + jgen.writeStartObject(); + jgen.writeFieldName(CustomToolsJson.PROPERTY_URL); + jgen.writeString(customToolsJson.url()); + jgen.writeFieldName(CustomToolsJson.PROPERTY_TOOLS); + jgen.writeStartArray(); + List tools = customToolsJson.tools(); + for (CustomToolJson tool : tools) { + jgen.writeObject(tool); + } + jgen.writeEndArray(); + jgen.writeEndObject(); + } + +} From a1ba16d07806ebc77bcc4161fcb63d0b2f9eb58f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Tue, 21 Jan 2025 16:54:47 +0100 Subject: [PATCH 2/8] #790: added to CHANGELOG.adoc --- CHANGELOG.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index f03264c85..6f830454a 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -6,6 +6,7 @@ This file documents all notable changes to https://github.com/devonfw/IDEasy[IDE Release with new features and bugfixes: +* https://github.com/devonfw/IDEasy/issues/790[#790]: Fix intellij plugin installation * https://github.com/devonfw/IDEasy/issues/915[#915]: custom-tools not working * https://github.com/devonfw/IDEasy/issues/916[#916]: download is missing status code error handling * https://github.com/devonfw/IDEasy/issues/757[#757]: Support to allow settings in code repository From 2c8dcd766100326fa5441575f737101064812790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Tue, 21 Jan 2025 16:56:07 +0100 Subject: [PATCH 3/8] #853: Added to CHANGELOG.adoc --- CHANGELOG.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 6f830454a..329b9a091 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -17,6 +17,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/498[#498]: Improvement of XML merger: resolve before merge * https://github.com/devonfw/IDEasy/issues/691[#691]: XMLMerger can not handle merge of subnodes properly * https://github.com/devonfw/IDEasy/issues/815[#815]: Links within IDEasy.pdf generally do not work +* https://github.com/devonfw/IDEasy/issues/853[#853]: NPE when trying to auto-complete after ide repository The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/18?closed=1[milestone 2025.01.001]. From b4a650577772a4fae810844e299c2436b5a9e88d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Tue, 21 Jan 2025 16:57:43 +0100 Subject: [PATCH 4/8] #914: Added to CHANGELOG.adoc --- CHANGELOG.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 329b9a091..d7fa00032 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -17,6 +17,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/498[#498]: Improvement of XML merger: resolve before merge * https://github.com/devonfw/IDEasy/issues/691[#691]: XMLMerger can not handle merge of subnodes properly * https://github.com/devonfw/IDEasy/issues/815[#815]: Links within IDEasy.pdf generally do not work +* https://github.com/devonfw/IDEasy/issues/914[#914]: Setup needs to create .bashrc if not existent * https://github.com/devonfw/IDEasy/issues/853[#853]: NPE when trying to auto-complete after ide repository The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/18?closed=1[milestone 2025.01.001]. From 20f462f19de9fc6de466da60af06dde7d7b5d797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Tue, 21 Jan 2025 16:59:50 +0100 Subject: [PATCH 5/8] #734: Fix CHANGELOG.adoc to correct release --- CHANGELOG.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index d7fa00032..ee73c43ed 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -19,6 +19,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/815[#815]: Links within IDEasy.pdf generally do not work * https://github.com/devonfw/IDEasy/issues/914[#914]: Setup needs to create .bashrc if not existent * https://github.com/devonfw/IDEasy/issues/853[#853]: NPE when trying to auto-complete after ide repository +* https://github.com/devonfw/IDEasy/issues/734[#734]: Improve ProcessResult: get out and err in order The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/18?closed=1[milestone 2025.01.001]. @@ -39,7 +40,6 @@ Then run the `setup` and all should work fine. Release with new features and bugfixes: -* https://github.com/devonfw/IDEasy/issues/734[#734]: Improve ProcessResult: get out and err in order * https://github.com/devonfw/IDEasy/issues/764[#764]: Fix IDEasy in CMD * https://github.com/devonfw/IDEasy/issues/774[#774]: HTTP proxy support not working properly * https://github.com/devonfw/IDEasy/issues/792[#792]: Honor new variable IDE_OPTIONS in ide command wrapper From 089f4c6a0fd14b34e0e36b26fa061fbbddccda2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohwiller?= Date: Tue, 21 Jan 2025 17:01:53 +0100 Subject: [PATCH 6/8] #894: Update issue title in CHANGELOG.adoc --- CHANGELOG.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index ee73c43ed..e2b632fc5 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -12,7 +12,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/757[#757]: Support to allow settings in code repository * https://github.com/devonfw/IDEasy/issues/826[#826]: Fix git settings check when settings folder is empty * https://github.com/devonfw/IDEasy/issues/898[#898]: Improved output of get-version/edition and uninstall/-plugin -* https://github.com/devonfw/IDEasy/issues/894[#894]: Fix ide.bat printing for initialization and error output +* https://github.com/devonfw/IDEasy/issues/894[#894]: ide.bat not printing if IDEasy was initialized * https://github.com/devonfw/IDEasy/issues/759[#759]: Add UpgradeSettingsCommandlet for the upgrade of legacy devonfw-ide settings to IDEasy * https://github.com/devonfw/IDEasy/issues/498[#498]: Improvement of XML merger: resolve before merge * https://github.com/devonfw/IDEasy/issues/691[#691]: XMLMerger can not handle merge of subnodes properly From 456fac1d16c43e668d64f9bd24105a0b9f1ee514 Mon Sep 17 00:00:00 2001 From: devonfw-core Date: Tue, 21 Jan 2025 16:10:34 +0000 Subject: [PATCH 7/8] set release version to 2025.01.001-beta --- .mvn/maven.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/maven.config b/.mvn/maven.config index 18f1acba3..eed3617dd 100644 --- a/.mvn/maven.config +++ b/.mvn/maven.config @@ -1 +1 @@ --Drevision=2025.01.001-beta-SNAPSHOT +-Drevision=2025.01.001-beta From d97386f6b75eeec1b95f890e213e3e3b417d280e Mon Sep 17 00:00:00 2001 From: devonfw-core Date: Tue, 21 Jan 2025 16:17:08 +0000 Subject: [PATCH 8/8] set next version to 2025.01.002-beta-SNAPSHOT --- .mvn/maven.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/maven.config b/.mvn/maven.config index eed3617dd..70a680831 100644 --- a/.mvn/maven.config +++ b/.mvn/maven.config @@ -1 +1 @@ --Drevision=2025.01.001-beta +-Drevision=2025.01.002-beta-SNAPSHOT