diff --git a/cli/pom.xml b/cli/pom.xml index 894134a1c2..1609facee8 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -49,11 +49,6 @@ slf4j-api - - ch.qos.logback - logback-classic - - org.graalvm.sdk nativeimage diff --git a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java index ac69e3b8d4..8961d773fb 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java +++ b/cli/src/main/java/com/devonfw/tools/ide/context/AbstractIdeContext.java @@ -150,6 +150,9 @@ public abstract class AbstractIdeContext implements IdeContext, IdeLogArgFormatt private final Map privacyMap; + /** Context used for logging */ + private static IdeContext loggingContext; + /** * The constructor. * @@ -220,6 +223,7 @@ public AbstractIdeContext(IdeStartContextImpl startContext, Path workingDirector } this.defaultToolRepository = new DefaultToolRepository(this); + loggingContext = this; this.mvnRepository = new MvnRepository(this); this.npmRepository = new NpmRepository(this); } @@ -1495,4 +1499,14 @@ public void writeVersionFile(VersionIdentifier version, Path installationPath) { getFileAccess().writeFileContent(version.toString(), versionFile); } + /** + * Gets the logging context. + * + * @return {@link IdeContext}. + */ + public static IdeContext getLoggingContext() { + + return loggingContext; + } + } diff --git a/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerOut.java b/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerOut.java index acd79c75ea..91cae563f1 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerOut.java +++ b/cli/src/main/java/com/devonfw/tools/ide/log/IdeSubLoggerOut.java @@ -17,6 +17,7 @@ public class IdeSubLoggerOut extends AbstractIdeSubLogger { * @param out the {@link Appendable} to {@link Appendable#append(CharSequence) write} log messages to. * @param colored - {@code true} for colored output according to {@link IdeLogLevel}, {@code false} otherwise. * @param minLogLevel the minimum log level (threshold). + * @param listener the {@link IdeLogListener} to listen to. */ public IdeSubLoggerOut(IdeLogLevel level, Appendable out, boolean colored, IdeLogLevel minLogLevel, IdeLogListener listener) { diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java new file mode 100644 index 0000000000..3dd361e418 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/IdeLoggerAdapter.java @@ -0,0 +1,388 @@ +package com.devonfw.tools.ide.serviceprovider; + +import org.slf4j.Logger; +import org.slf4j.Marker; + +import com.devonfw.tools.ide.context.AbstractIdeContext; +import com.devonfw.tools.ide.context.IdeContext; + +/** + * Implementation of {@link Logger}. + */ +public class IdeLoggerAdapter implements Logger { + + private final String name; + + private final IdeContext loggingContext; + + /** + * The constructor. + * + * @param name of the logger. + */ + public IdeLoggerAdapter(String name) { + + this.name = name; + // TODO: check for WireMock, com.github.jknack.handlebars.Handlebars, org.eclipse.jetty.util.Jetty + if (name.equals("WireMock") || name.contains("jknack") || name.contains("jetty")) { + loggingContext = null; + return; + } + loggingContext = AbstractIdeContext.getLoggingContext(); + } + + @Override + public String getName() { + + return name; + } + + @Override + public boolean isTraceEnabled() { + return loggingContext.trace().isEnabled(); + } + + @Override + public void trace(String s) { + loggingContext.trace(s); + } + + @Override + public void trace(String s, Object o) { + loggingContext.trace(s, o); + } + + @Override + public void trace(String s, Object o, Object o1) { + loggingContext.trace(s, o, o1); + } + + @Override + public void trace(String s, Object... objects) { + loggingContext.trace(s, objects); + } + + @Override + public void trace(String s, Throwable throwable) { + loggingContext.trace(s, throwable); + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return loggingContext.trace().isEnabled(); + } + + @Override + public void trace(Marker marker, String s) { + loggingContext.trace(s); + } + + @Override + public void trace(Marker marker, String s, Object o) { + loggingContext.trace(s, o); + } + + @Override + public void trace(Marker marker, String s, Object o, Object o1) { + loggingContext.trace(s, o, o1); + } + + @Override + public void trace(Marker marker, String s, Object... objects) { + loggingContext.trace(s, objects); + } + + @Override + public void trace(Marker marker, String s, Throwable throwable) { + loggingContext.trace(s, throwable); + } + + @Override + public boolean isDebugEnabled() { + if (loggingContext != null) { + return loggingContext.debug().isEnabled(); + } else { + return false; + } + + } + + @Override + public void debug(String s) { + if (loggingContext != null) { + loggingContext.debug(s); + } + } + + @Override + public void debug(String s, Object o) { + if (loggingContext != null) { + loggingContext.debug(s, o); + } + } + + @Override + public void debug(String s, Object o, Object o1) { + if (loggingContext != null) { + loggingContext.debug(s, o, o1); + } + } + + @Override + public void debug(String s, Object... objects) { + if (loggingContext != null) { + loggingContext.debug(s, objects); + } + } + + @Override + public void debug(String s, Throwable throwable) { + if (loggingContext != null) { + loggingContext.debug(s, throwable); + } + } + + @Override + public boolean isDebugEnabled(Marker marker) { + if (loggingContext != null) { + return loggingContext.debug().isEnabled(); + } else { + return false; + } + } + + @Override + public void debug(Marker marker, String s) { + loggingContext.debug(s); + } + + @Override + public void debug(Marker marker, String s, Object o) { + loggingContext.debug(s, o); + } + + @Override + public void debug(Marker marker, String s, Object o, Object o1) { + loggingContext.debug(s, o, o1); + } + + @Override + public void debug(Marker marker, String s, Object... objects) { + loggingContext.debug(s, objects); + } + + @Override + public void debug(Marker marker, String s, Throwable throwable) { + loggingContext.debug(s, throwable); + } + + @Override + public boolean isInfoEnabled() { + if (loggingContext != null) { + return loggingContext.info().isEnabled(); + } else { + return false; + } + } + + @Override + public void info(String s) { + if (loggingContext != null) { + loggingContext.info(s); + } + } + + @Override + public void info(String s, Object o) { + if (loggingContext != null) { + loggingContext.info(s, o); + } + } + + @Override + public void info(String s, Object o, Object o1) { + if (loggingContext != null) { + loggingContext.info(s, o, o1); + } + } + + @Override + public void info(String s, Object... objects) { + if (loggingContext != null) { + loggingContext.info(s, objects); + } + } + + @Override + public void info(String s, Throwable throwable) { + loggingContext.info(s, throwable); + } + + @Override + public boolean isInfoEnabled(Marker marker) { + return loggingContext.info().isEnabled(); + } + + @Override + public void info(Marker marker, String s) { + loggingContext.info(s); + } + + @Override + public void info(Marker marker, String s, Object o) { + loggingContext.info(s, o); + } + + @Override + public void info(Marker marker, String s, Object o, Object o1) { + loggingContext.info(s, o, o1); + } + + @Override + public void info(Marker marker, String s, Object... objects) { + loggingContext.info(s, objects); + } + + @Override + public void info(Marker marker, String s, Throwable throwable) { + loggingContext.info(s, throwable); + } + + @Override + public boolean isWarnEnabled() { + return loggingContext.warning().isEnabled(); + } + + @Override + public void warn(String s) { + loggingContext.warning(s); + } + + @Override + public void warn(String s, Object o) { + loggingContext.warning(s, o); + } + + @Override + public void warn(String s, Object... objects) { + loggingContext.warning(s, objects); + } + + @Override + public void warn(String s, Object o, Object o1) { + loggingContext.warning(s, o, o1); + } + + @Override + public void warn(String s, Throwable throwable) { + if (loggingContext != null) { + loggingContext.warning(s, throwable); + } + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return loggingContext.warning().isEnabled(); + } + + @Override + public void warn(Marker marker, String s) { + loggingContext.warning(s); + } + + @Override + public void warn(Marker marker, String s, Object o) { + loggingContext.warning(s, o); + } + + @Override + public void warn(Marker marker, String s, Object o, Object o1) { + loggingContext.warning(s, o, o1); + } + + @Override + public void warn(Marker marker, String s, Object... objects) { + loggingContext.warning(s, objects); + } + + @Override + public void warn(Marker marker, String s, Throwable throwable) { + loggingContext.warning(s, throwable); + } + + @Override + public boolean isErrorEnabled() { + if (loggingContext != null) { + return loggingContext.error().isEnabled(); + } else { + return false; + } + } + + @Override + public void error(String s) { + if (loggingContext != null) { + loggingContext.error(s); + } + } + + @Override + public void error(String s, Object o) { + if (loggingContext != null) { + loggingContext.error(s, o); + } + } + + @Override + public void error(String s, Object o, Object o1) { + loggingContext.error(s, o, o1); + } + + @Override + public void error(String s, Object... objects) { + if (loggingContext != null) { + loggingContext.error(s, objects); + } + } + + @Override + public void error(String s, Throwable throwable) { + if (loggingContext != null) { + loggingContext.error(s, throwable); + } + } + + @Override + public boolean isErrorEnabled(Marker marker) { + if (loggingContext != null) { + return loggingContext.error().isEnabled(); + } else { + return false; + } + } + + @Override + public void error(Marker marker, String s) { + loggingContext.error(s); + } + + @Override + public void error(Marker marker, String s, Object o) { + loggingContext.error(s, o); + } + + @Override + public void error(Marker marker, String s, Object o, Object o1) { + loggingContext.error(s, o, o1); + } + + @Override + public void error(Marker marker, String s, Object... objects) { + loggingContext.error(s, objects); + } + + @Override + public void error(Marker marker, String s, Throwable throwable) { + loggingContext.error(s, throwable); + } +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactoryImpl.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactoryImpl.java new file mode 100644 index 0000000000..69bf038107 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestLoggerFactoryImpl.java @@ -0,0 +1,16 @@ +package com.devonfw.tools.ide.serviceprovider; + +import org.slf4j.ILoggerFactory; +import org.slf4j.Logger; + +/** + * Implementation of {@link ILoggerFactory}. + */ +public class TestLoggerFactoryImpl implements ILoggerFactory { + + @Override + public Logger getLogger(String name) { + + return new IdeLoggerAdapter(name); + } +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProviderImpl.java b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProviderImpl.java new file mode 100644 index 0000000000..62fc569181 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/serviceprovider/TestProviderImpl.java @@ -0,0 +1,46 @@ +package com.devonfw.tools.ide.serviceprovider; + +import org.slf4j.ILoggerFactory; +import org.slf4j.IMarkerFactory; +import org.slf4j.helpers.NOPMDCAdapter; +import org.slf4j.spi.MDCAdapter; +import org.slf4j.spi.SLF4JServiceProvider; + +/** + * Implementation of {@link SLF4JServiceProvider}. + */ +public class TestProviderImpl implements SLF4JServiceProvider { + + private final String REQUESTED_API_VERSION = "2.0.12"; + private TestLoggerFactoryImpl testLoggerFactory; + + + @Override + public ILoggerFactory getLoggerFactory() { + + return testLoggerFactory; + } + + @Override + public IMarkerFactory getMarkerFactory() { + + return null; + } + + @Override + public MDCAdapter getMDCAdapter() { + + return new NOPMDCAdapter(); + } + + @Override + public String getRequestedApiVersion() { + + return REQUESTED_API_VERSION; + } + + @Override + public void initialize() { + testLoggerFactory = new TestLoggerFactoryImpl(); + } +} diff --git a/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider new file mode 100644 index 0000000000..c70584fc82 --- /dev/null +++ b/cli/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider @@ -0,0 +1 @@ +com.devonfw.tools.ide.serviceprovider.TestProviderImpl diff --git a/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java b/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java index b7413879cc..88cc3b9c84 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java +++ b/cli/src/test/java/com/devonfw/tools/ide/context/IdeSlf4jContext.java @@ -3,7 +3,7 @@ import java.nio.file.Path; import com.devonfw.tools.ide.log.IdeLogLevel; -import com.devonfw.tools.ide.log.IdeSubLoggerSlf4j; +import com.devonfw.tools.ide.log.IdeSubLoggerOut; /** * Implementation of {@link IdeContext} for testing. @@ -26,7 +26,7 @@ public IdeSlf4jContext() { */ public IdeSlf4jContext(Path workingDirectory) { - super(new IdeStartContextImpl(IdeLogLevel.TRACE, IdeSubLoggerSlf4j::new), workingDirectory); + super(new IdeStartContextImpl(IdeLogLevel.TRACE, level -> new IdeSubLoggerOut(level, null, true, IdeLogLevel.TRACE, null)), workingDirectory); } } diff --git a/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLogger.java b/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLogger.java index ca889bbc22..ed2e3f18c4 100644 --- a/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLogger.java +++ b/cli/src/test/java/com/devonfw/tools/ide/log/IdeTestLogger.java @@ -24,7 +24,7 @@ public IdeTestLogger(IdeLogLevel minLogLevel) { private IdeTestLogger(List entries, IdeLogLevel minLogLevel, IdeLogListenerCollector collector) { - super(minLogLevel, level -> new IdeSubLoggerSlf4j(level, collector)); + super(minLogLevel, level -> new IdeSubLoggerOut(level, null, true, minLogLevel, collector)); this.collector = collector; } diff --git a/url-updater/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/url-updater/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider new file mode 100644 index 0000000000..0bb90a9c2b --- /dev/null +++ b/url-updater/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider @@ -0,0 +1 @@ +ch.qos.logback.classic.spi.LogbackServiceProvider diff --git a/url-updater/src/test/java/com/devonfw/tools/ide/url/updater/UrlUpdaterTest.java b/url-updater/src/test/java/com/devonfw/tools/ide/url/updater/UrlUpdaterTest.java index 332ca9af24..0e7fb2d2aa 100644 --- a/url-updater/src/test/java/com/devonfw/tools/ide/url/updater/UrlUpdaterTest.java +++ b/url-updater/src/test/java/com/devonfw/tools/ide/url/updater/UrlUpdaterTest.java @@ -31,7 +31,7 @@ import com.github.tomakehurst.wiremock.junit5.WireMockTest; /** - * Test of {@link com.devonfw.tools.ide.url.updater.UrlUpdater} using wiremock to simulate network downloads. + * Test of {@link UrlUpdater} using wiremock to simulate network downloads. */ @WireMockTest public class UrlUpdaterTest extends AbstractUrlUpdaterTest { @@ -42,7 +42,7 @@ public class UrlUpdaterTest extends AbstractUrlUpdaterTest { private final static String TEST_DATA_ROOT = "src/test/resources/integrationtest/UrlUpdaterTest"; /** - * Tests if the {@link com.devonfw.tools.ide.url.updater.UrlUpdater} can automatically add a missing OS (in this case the linux_x64) + * Tests if the {@link UrlUpdater} can automatically add a missing OS (in this case the linux_x64) * * @param tempDir Temporary directory * @param wmRuntimeInfo wireMock server on a random port @@ -209,7 +209,7 @@ public void testSuccessStateUpdatedAfterError(@TempDir Path tempDir, WireMockRun } /** - * Tests if the the tool version gets entirely removed if all versions are broken for a long time. + * Tests if the tool version gets entirely removed if all versions are broken for a long time. * * @param tempDir Temporary directory * @param wmRuntimeInfo wireMock server on a random port @@ -254,7 +254,7 @@ public void testVersionRemovedIfErrorPersists(@TempDir Path tempDir, WireMockRun } /** - * Tests if the {@link com.devonfw.tools.ide.url.updater.UrlUpdater} will fail resolving a server with a Content-Type:text header response. + * Tests if the {@link UrlUpdater} will fail resolving a server with a Content-Type:text header response. *

* See: #1343 for reference. * @@ -281,7 +281,7 @@ public void testUrlUpdaterWithTextContentTypeWillNotCreateStatusJson(@TempDir Pa } /** - * Tests if the {@link com.devonfw.tools.ide.url.updater.UrlUpdater} will handle the literally latest version of a tool correctly + * Tests if the {@link UrlUpdater} will handle the literally latest version of a tool correctly * * @param tempDir Temporary directory * @param wmRuntimeInfo wireMock server on a random port