Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(main) Use Maven Eclipse Sisu to inject components #977

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-maven-4.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ jobs:
- name: Maven version
run: mvn -version
- name: Build & Test
run: mvn -B -Prun-its clean verify -D"maven.version=${{ matrix.maven }}" -D"plexus-utils.version=4.0.2"
run: mvn -B -Prun-its -Pmaven4 clean verify

5 changes: 5 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ For a detailed view of what has changed, refer to the {uri-repo}/commits/main[co

== Unreleased

Improvements (for all modules)::

* Use Maven Eclipse Sisu to inject components (allowed refactors to increase code re-use) (#945)
* Centralize Maven4 configurations in a profile in the parent (#945)

Bug Fixes (Site Modules)::

* Fix resolution of baseDir for Doxia modules (#968)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.asciidoctor.maven.site;

import javax.inject.Inject;
import javax.inject.Provider;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
Expand All @@ -12,14 +11,8 @@
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.project.MavenProject;
import org.asciidoctor.Asciidoctor;
import org.asciidoctor.Attributes;
import org.asciidoctor.AttributesBuilder;
import org.asciidoctor.Options;
import org.asciidoctor.OptionsBuilder;
import org.asciidoctor.SafeMode;
import org.asciidoctor.maven.commons.StringUtils;
import org.asciidoctor.maven.log.LogHandler;
import org.asciidoctor.maven.log.LogRecordFormatter;
import org.asciidoctor.maven.log.LogRecordsProcessors;
import org.asciidoctor.maven.log.MemoryLogHandler;
import org.asciidoctor.maven.site.SiteConverterDecorator.Result;
Expand All @@ -29,8 +22,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.asciidoctor.maven.site.SiteBaseDirResolver.resolveBaseDir;

/**
* This class is used by <a href="https://maven.apache.org/doxia/overview.html">the Doxia framework</a>
* to handle the actual parsing of the AsciiDoc input files into HTML to be consumed/wrapped
Expand All @@ -43,15 +34,28 @@
@Component(role = Parser.class, hint = AsciidoctorConverterDoxiaParser.ROLE_HINT)
public class AsciidoctorConverterDoxiaParser extends AbstractTextParser {

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

@Inject
protected Provider<MavenProject> mavenProjectProvider;

/**
* The role hint for the {@link AsciidoctorConverterDoxiaParser} Plexus component.
*/
public static final String ROLE_HINT = "asciidoc";
static final String ROLE_HINT = "asciidoc";

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

private final MavenProject mavenProject;
private final SiteConversionConfigurationParser siteConfigParser;
private final LogHandlerFactory logHandlerFactory;
private final SiteConverterDecorator siteConverter;

@Inject
public AsciidoctorConverterDoxiaParser(MavenProject mavenProject,
SiteConversionConfigurationParser siteConfigParser,
LogHandlerFactory logHandlerFactory,
SiteConverterDecorator siteConverter) {
this.mavenProject = mavenProject;
this.siteConfigParser = siteConfigParser;
this.logHandlerFactory = logHandlerFactory;
this.siteConverter = siteConverter;
}

/**
* {@inheritDoc}
Expand All @@ -68,27 +72,24 @@ public void parse(Reader reader, Sink sink, String reference) throws ParseExcept
return;
}

final MavenProject project = mavenProjectProvider.get();
final Xpp3Dom siteConfig = getSiteConfig(project);
final File siteDirectory = resolveBaseDir(project.getBasedir(), siteConfig);
final SiteConversionConfiguration conversionConfig = siteConfigParser.processAsciiDocConfig(mavenProject, ROLE_HINT);
final Xpp3Dom asciidocConfig = conversionConfig.getAsciidocConfig();
final File siteDirectory = conversionConfig.getSiteBaseDir();

// Doxia handles a single instance of this class and invokes it multiple times.
// We need to ensure certain elements are initialized only once to avoid errors.
// Note, this cannot be done in the constructor because mavenProjectProvider in set after construction.
// And overriding init and other methods form parent classes does not work.
final Asciidoctor asciidoctor = Asciidoctor.Factory.create();

SiteConversionConfiguration conversionConfig = new SiteConversionConfigurationParser(project)
.processAsciiDocConfig(siteConfig, defaultOptions(siteDirectory), defaultAttributes());
for (String require : conversionConfig.getRequires()) {
requireLibrary(asciidoctor, require);
}

final LogHandler logHandler = getLogHandlerConfig(siteConfig);
final MemoryLogHandler memoryLogHandler = asciidoctorLoggingSetup(asciidoctor, siteDirectory);
final LogHandler logHandler = logHandlerFactory.getConfiguration(asciidocConfig);
final MemoryLogHandler memoryLogHandler = logHandlerFactory.create(asciidoctor, siteDirectory, logger);

final SiteConverterDecorator siteConverter = new SiteConverterDecorator(asciidoctor);
final Result headerMetadata = siteConverter.process(source, conversionConfig.getOptions());
final Result headerMetadata = siteConverter.process(asciidoctor, source, conversionConfig.getOptions());

try {
// process log messages according to mojo configuration
Expand All @@ -97,7 +98,7 @@ public void parse(Reader reader, Sink sink, String reference) throws ParseExcept
if (logHandler.getOutputToConsole() && StringUtils.isNotBlank(reference)) {
memoryLogHandler.processAll();
}
new LogRecordsProcessors(logHandler, siteDirectory, errorMessage -> logger.error(errorMessage))
new LogRecordsProcessors(logHandler, siteDirectory, logger::error)
.processLogRecords(memoryLogHandler);
}
} catch (Exception exception) {
Expand All @@ -110,45 +111,6 @@ public void parse(Reader reader, Sink sink, String reference) throws ParseExcept
sink.rawText(headerMetadata.getHtml());
}

private MemoryLogHandler asciidoctorLoggingSetup(Asciidoctor asciidoctor, File siteDirectory) {

final MemoryLogHandler memoryLogHandler = new MemoryLogHandler(false,
logRecord -> logger.info(LogRecordFormatter.format(logRecord, siteDirectory)));
asciidoctor.registerLogHandler(memoryLogHandler);
// disable default console output of AsciidoctorJ
java.util.logging.Logger.getLogger("asciidoctor").setUseParentHandlers(false);
return memoryLogHandler;
}

private LogHandler getLogHandlerConfig(Xpp3Dom siteConfig) {
Xpp3Dom asciidoc = siteConfig == null ? null : siteConfig.getChild("asciidoc");
return new SiteLogHandlerDeserializer().deserialize(asciidoc);
}

protected Xpp3Dom getSiteConfig(MavenProject project) {
return project.getGoalConfiguration("org.apache.maven.plugins", "maven-site-plugin", "site", "site");
}


// The possible baseDir based on configuration are:
//
// with nothing : src/site + /asciidoc
// with locale : src/site + {locale} + /asciidoc
// with siteDirectory : {siteDirectory} + /asciidoc
// with siteDirectory + locale : {siteDirectory} + {locale} + /asciidoc
protected OptionsBuilder defaultOptions(File siteDirectory) {
return Options.builder()
.backend("xhtml")
.safe(SafeMode.UNSAFE)
.baseDir(new File(siteDirectory, ROLE_HINT).getAbsoluteFile());
}

protected AttributesBuilder defaultAttributes() {
return Attributes.builder()
.attribute("idprefix", "@")
.attribute("showtitle", "@");
}

private void requireLibrary(Asciidoctor asciidoctor, String require) {
if (!(require = require.trim()).isEmpty()) {
try {
Expand All @@ -158,4 +120,5 @@ private void requireLibrary(Asciidoctor asciidoctor, String require) {
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* <a href="https://maven.apache.org/doxia/references/">Doxia provided modules</a>.
*
* @author jdlee
* @since 0.1.2.1
*/
@Component(role = ParserModule.class, hint = AsciidoctorConverterDoxiaParser.ROLE_HINT)
public class AsciidoctorConverterDoxiaParserModule extends AbstractParserModule {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.asciidoctor.maven.site;

import javax.inject.Singleton;
import java.util.Map;

import org.asciidoctor.Asciidoctor;
Expand All @@ -10,16 +11,14 @@
/**
* Asciidoctor conversion wrapper for maven-site integration.
* In addition to conversion, handles header metadata extraction.
*
* @author abelsromero
* @since 3.0.0
*/
@Singleton
class SiteConverterDecorator {

private final Asciidoctor asciidoctor;

SiteConverterDecorator(Asciidoctor asciidoctor) {
this.asciidoctor = asciidoctor;
}

Result process(String content, Options options) {
Result process(Asciidoctor asciidoctor, String content, Options options) {
final Document document = asciidoctor.load(content, headerProcessingMetadata(options));
final HeaderMetadata headerMetadata = HeaderMetadata.from(document);

Expand Down Expand Up @@ -61,5 +60,4 @@ String getHtml() {
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import static org.asciidoctor.maven.site.AsciidoctorConverterDoxiaParser.ROLE_HINT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.codehaus.plexus.util.ReflectionUtils.setVariableValueInObject;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -247,14 +246,14 @@ void should_fail_when_logHandler_failIf_is_WARNING() {
}

@SneakyThrows
private javax.inject.Provider<MavenProject> createMavenProjectMock(String configuration) {
private MavenProject createMockMavenProject(String configuration) {
MavenProject mockProject = Mockito.mock(MavenProject.class);
when(mockProject.getBasedir())
.thenReturn(new File("."));
when(mockProject.getGoalConfiguration(anyString(), anyString(), anyString(), anyString()))
.thenReturn(configuration != null ? Xpp3DomBuilder.build(new StringReader(configuration)) : null);

return () -> mockProject;
return mockProject;
}

@SneakyThrows
Expand All @@ -264,16 +263,19 @@ private AsciidoctorConverterDoxiaParser mockAsciidoctorDoxiaParser() {

@SneakyThrows
private AsciidoctorConverterDoxiaParser mockAsciidoctorDoxiaParser(String configuration) {
AsciidoctorConverterDoxiaParser parser = new AsciidoctorConverterDoxiaParser();
setVariableValueInObject(parser, "mavenProjectProvider", createMavenProjectMock(configuration));
return parser;
return new AsciidoctorConverterDoxiaParser(
createMockMavenProject(configuration),
new SiteConversionConfigurationParser(new SiteBaseDirResolver()),
new LogHandlerFactory(),
new SiteConverterDecorator()
);
}

private Sink createSinkMock() {
return new TextProviderSink();
}

class TextProviderSink extends AbstractTextSink {
static class TextProviderSink extends AbstractTextSink {
String text;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ class SiteConverterDecoratorTest {
"Hello, AsciiDoc!\n================"
})
void should_extract_title_from_header(String title) {
SiteConverterDecorator siteConverter = new SiteConverterDecorator(asciidoctor);
SiteConverterDecorator siteConverter = new SiteConverterDecorator();

Options options = defaultOptions();
Result result = siteConverter.process(title + "\n", options);
Result result = siteConverter.process(asciidoctor, title + "\n", options);

HeaderMetadata headerMetadata = result.getHeaderMetadata();
assertThat(headerMetadata.getTitle()).isEqualTo("Hello, AsciiDoc!");
Expand All @@ -40,7 +40,7 @@ void should_extract_title_from_header(String title) {

@Test
void should_extract_title_from_attribute() {
SiteConverterDecorator siteConverter = new SiteConverterDecorator(asciidoctor);
SiteConverterDecorator siteConverter = new SiteConverterDecorator();

Options options = Options.builder()
.safe(SafeMode.UNSAFE)
Expand All @@ -51,7 +51,7 @@ void should_extract_title_from_attribute() {
.attribute("who", "me")
.build())
.build();
Result result = siteConverter.process("= Hello, {who}!\n", options);
Result result = siteConverter.process(asciidoctor, "= Hello, {who}!\n", options);

HeaderMetadata headerMetadata = result.getHeaderMetadata();
assertThat(headerMetadata.getTitle()).isEqualTo("Hello, me!");
Expand All @@ -62,10 +62,10 @@ void should_extract_title_from_attribute() {
@ParameterizedTest
@MethodSource("authorsProvider")
void should_extract_author(String content, String expected) {
SiteConverterDecorator siteConverter = new SiteConverterDecorator(asciidoctor);
SiteConverterDecorator siteConverter = new SiteConverterDecorator();

Options options = defaultOptions();
Result result = siteConverter.process(content + "\n", options);
Result result = siteConverter.process(asciidoctor, content + "\n", options);

HeaderMetadata headerMetadata = result.getHeaderMetadata();
assertThat(headerMetadata.getAuthors())
Expand All @@ -84,11 +84,11 @@ private static Stream<Arguments> authorsProvider() {

@Test
void should_extract_author_from_attribute() {
SiteConverterDecorator siteConverter = new SiteConverterDecorator(asciidoctor);
SiteConverterDecorator siteConverter = new SiteConverterDecorator();

String content = "= Hello, AsciiDoc!";
Options options = optionsWithAttributes(Collections.singletonMap("author", "From Attr"));
Result result = siteConverter.process(content + "\n", options);
Result result = siteConverter.process(asciidoctor, content + "\n", options);

HeaderMetadata headerMetadata = result.getHeaderMetadata();
assertThat(headerMetadata.getAuthors())
Expand All @@ -98,10 +98,10 @@ void should_extract_author_from_attribute() {

@Test
void should_extract_multiple_authors() {
SiteConverterDecorator siteConverter = new SiteConverterDecorator(asciidoctor);
SiteConverterDecorator siteConverter = new SiteConverterDecorator();

String content = "= Hello, AsciiDoc!\nfirstname1 lastname2; firstname3 middlename4 lastname5";
Result result = siteConverter.process(content + "\n", defaultOptions());
Result result = siteConverter.process(asciidoctor, content + "\n", defaultOptions());

HeaderMetadata headerMetadata = result.getHeaderMetadata();
assertThat(headerMetadata.getAuthors())
Expand All @@ -111,10 +111,10 @@ void should_extract_multiple_authors() {

@Test
void should_extract_datetime_generated() {
SiteConverterDecorator siteConverter = new SiteConverterDecorator(asciidoctor);
SiteConverterDecorator siteConverter = new SiteConverterDecorator();

String content = "= Hello, AsciiDoc!";
Result result = siteConverter.process(content + "\n", defaultOptions());
Result result = siteConverter.process(asciidoctor, content + "\n", defaultOptions());

HeaderMetadata headerMetadata = result.getHeaderMetadata();
assertThat(headerMetadata.getDateTime()).matches("(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2}) .*");
Expand All @@ -123,11 +123,11 @@ void should_extract_datetime_generated() {

@Test
void should_extract_datetime_from_attribute() {
SiteConverterDecorator siteConverter = new SiteConverterDecorator(asciidoctor);
SiteConverterDecorator siteConverter = new SiteConverterDecorator();

String content = "= Hello, AsciiDoc!";
Options options = optionsWithAttributes(Collections.singletonMap("docdatetime", "2024-11-22"));
Result result = siteConverter.process(content + "\n", options);
Result result = siteConverter.process(asciidoctor, content + "\n", options);

HeaderMetadata headerMetadata = result.getHeaderMetadata();
assertThat(headerMetadata.getDateTime()).isEqualTo("2024-11-22");
Expand Down
5 changes: 1 addition & 4 deletions asciidoctor-maven-commons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@
</description>
<url>https://github.com/asciidoctor/asciidoctor-maven-plugin</url>

<properties>
<plexus-utils.version>3.5.1</plexus-utils.version>
</properties>

<dependencies>
<dependency>
<groupId>org.asciidoctor</groupId>
Expand All @@ -37,6 +33,7 @@
<version>${maven.version}</version>
<scope>provided</scope>
</dependency>
<!-- Required: see https://issues.apache.org/jira/browse/MNG-6965 -->
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
Expand Down
Loading