attributes;
+ /**
+ * Parser configurations (per matching Doxia markup source file path patterns).
+ * Each configuration item has the following format:
+ *
+ *
+ * <parserId>
+ * <configurations>
+ * <configuration>
+ * <patterns>
+ * <pattern>glob:**/*.md</pattern><!-- is either glob or regex syntax with the according prefix -->
+ * </patterns>
+ * <!-- all configurations apart from pattern are directly applied to the underlying parser -->
+ * <emitComments>true</emitComments><!-- false by default -->
+ * <emitAnchorsForIndexableEntries>false</emitAnchorsForIndexableEntries><!-- true by default -->
+ * </configuration>
+ * </configurations>
+ * </parserId>
+ *
+ * The configuration is only applied if both
+ *
+ * - the parser id matches the parser used for a specific markup source file and
+ * - one of the given patterns matches the Doxia markup source file path (or no pattern is given at all).
+ *
+ *
+ * The first matching configuration wins (i.e. is applied).
+ * @since 4.0.0
+ * @see java.nio.file.FileSystem#getPathMatcher(String) FileSystem.getPathMatcher(String) for the supported patterns
+ */
+ @Parameter
+ private Map> parserConfigurations;
+
/**
* Site renderer.
*/
@@ -270,7 +304,12 @@ private ReportPlugin[] getReportingPlugins() {
return reportingPlugins.toArray(new ReportPlugin[0]);
}
- protected SiteRenderingContext createSiteRenderingContext(Locale locale)
+ protected ParserConfiguratorImpl createParserConfigurator() throws ComponentLookupException {
+ return new ParserConfiguratorImpl(
+ parserConfigurations, mavenSession.getContainer(), mojoExecution.getMojoDescriptor());
+ }
+
+ protected SiteRenderingContext createSiteRenderingContext(Locale locale, ParserConfigurator parserConfigurator)
throws MojoExecutionException, IOException, MojoFailureException {
SiteModel siteModel = prepareSiteModel(locale);
Map templateProperties = new HashMap<>();
@@ -332,7 +371,7 @@ protected SiteRenderingContext createSiteRenderingContext(Locale locale)
context.setProcessedContentOutput(processedDir);
}
}
-
+ context.setParserConfigurator(parserConfigurator);
return context;
}
diff --git a/src/main/java/org/apache/maven/plugins/site/render/ParserConfiguratorImpl.java b/src/main/java/org/apache/maven/plugins/site/render/ParserConfiguratorImpl.java
new file mode 100644
index 00000000..673055c9
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/site/render/ParserConfiguratorImpl.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.plugins.site.render;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.maven.doxia.parser.Parser;
+import org.apache.maven.doxia.siterenderer.ParserConfigurator;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
+import org.codehaus.plexus.component.configurator.ComponentConfigurator;
+import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+
+/**
+ * Configures a parser based on a {@link PlexusConfiguration} for a particular parser id and optionally matching one of multiple patterns.
+ * It internally leverages the {@link ComponentConfigurator} for calling the right methods inside the parser implementation.
+ */
+public class ParserConfiguratorImpl implements ParserConfigurator, Closeable {
+
+ private static final class ParserConfigurationKey {
+
+ ParserConfigurationKey(String parserId, PlexusConfiguration patternsConfiguration) {
+ this(parserId, PlexusConfigurationUtils.getStringArrayValues(patternsConfiguration));
+ }
+
+ ParserConfigurationKey(String parserId, Collection patterns) {
+ this.parserId = parserId;
+ // lazily populate all matchers
+ matchers = patterns.stream()
+ .map(p -> FileSystems.getDefault().getPathMatcher(p))
+ .collect(Collectors.toList());
+ }
+
+ private final String parserId;
+
+ /**
+ * List of {@link PathMatcher}s for all of the patterns passed to the constructor
+ */
+ private List matchers;
+
+ /**
+ * Returns {@code true} the given file path matches one of the {@link #patterns} given via {@link #addPattern(String)}
+ * @param filePath the file path to check
+ * @return {@code true} if the given file path matches at least one of the patterns, {@code false} otherwise.
+ * @throws IllegalArgumentException
+ * If one of the patterns does not comply with the form: {@code syntax:pattern}
+ * @throws java.util.regex.PatternSyntaxException
+ * If one of the regex patterns is invalid
+ * @throws UnsupportedOperationException
+ * If one of the patterns syntax prefix is not known to the implementation
+ * @see FileSystem#getPathMatcher(String)
+ */
+ public boolean matches(String parserId, Path filePath) {
+ if (this.parserId.equals(parserId)) {
+ return false;
+ }
+ if (matchers.isEmpty()) {
+ return true; // no patterns mean always match
+ }
+ return matchers.stream().anyMatch(m -> m.matches(filePath));
+ }
+ }
+
+ private final org.codehaus.plexus.classworlds.realm.ClassRealm pluginClassRealm;
+ private final PlexusContainer plexusContainer;
+ private final ComponentConfigurator componentConfigurator;
+
+ private final Map parserConfigurations;
+
+ public ParserConfiguratorImpl(
+ Map> parserConfigurations,
+ PlexusContainer plexusContainer,
+ MojoDescriptor mojoDescriptor)
+ throws ComponentLookupException {
+ this.parserConfigurations = new LinkedHashMap<>();
+ if (parserConfigurations != null) {
+ for (Map.Entry> parserConfigurationPerId :
+ parserConfigurations.entrySet()) {
+ String parserId = parserConfigurationPerId.getKey();
+ for (PlexusConfiguration configuration : parserConfigurationPerId.getValue()) {
+ ParserConfigurationKey key =
+ new ParserConfigurationKey(parserId, configuration.getChild("patterns"));
+ this.parserConfigurations.put(key, configuration);
+ }
+ }
+ }
+ pluginClassRealm = mojoDescriptor.getRealm();
+ this.plexusContainer = plexusContainer;
+ componentConfigurator = getComponentConfigurator(mojoDescriptor.getComponentConfigurator());
+ }
+
+ ComponentConfigurator getComponentConfigurator(String configuratorId) throws ComponentLookupException {
+ // logic copied from
+ // https://github.com/apache/maven/blob/267de063eec17111688fd1a27d4e3aae6c8d0c51/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java#L696C9-L700C10
+ if (configuratorId == null || configuratorId.isEmpty()) {
+ configuratorId = "basic"; // TODO: support v4
+ }
+ return plexusContainer.lookup(ComponentConfigurator.class, configuratorId);
+ }
+
+ public void configureParser(PlexusConfiguration configuration, Parser parser)
+ throws ComponentConfigurationException {
+ componentConfigurator.configureComponent(parser, configuration, pluginClassRealm);
+ }
+
+ @Override
+ public void close() throws IOException {
+ try {
+ plexusContainer.release(componentConfigurator);
+ } catch (ComponentLifecycleException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public boolean configure(String parserId, Path filePath, Parser parser) {
+ Optional config = parserConfigurations.entrySet().stream()
+ .filter(c -> c.getKey().matches(parserId, filePath))
+ .findFirst()
+ .map(Map.Entry::getValue);
+ config.ifPresent(c -> {
+ try {
+ configureParser(c, parser);
+ } catch (ComponentConfigurationException e) {
+ throw new IllegalStateException("Could not configure parser " + parser, e);
+ }
+ });
+ return config.isPresent();
+ }
+}
diff --git a/src/main/java/org/apache/maven/plugins/site/render/PlexusConfigurationUtils.java b/src/main/java/org/apache/maven/plugins/site/render/PlexusConfigurationUtils.java
new file mode 100644
index 00000000..09d53b92
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/site/render/PlexusConfigurationUtils.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.plugins.site.render;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+
+public class PlexusConfigurationUtils {
+
+ private PlexusConfigurationUtils() {
+ // not supposed to be instantiated
+ }
+
+ /**
+ * Retrieves all string values from the children of the given {@link PlexusConfiguration}
+ * @param arrayContainer the configuration containing the array container (may be {@code null})
+ * @return the list of string values
+ */
+ static List getStringArrayValues(PlexusConfiguration arrayContainer) {
+ if (arrayContainer == null) {
+ return Collections.emptyList();
+ }
+ List stringValues = new ArrayList<>();
+ for (PlexusConfiguration item : arrayContainer.getChildren()) {
+ stringValues.add(item.getValue());
+ }
+ return stringValues;
+ }
+}
diff --git a/src/main/java/org/apache/maven/plugins/site/render/SiteMojo.java b/src/main/java/org/apache/maven/plugins/site/render/SiteMojo.java
index f6431abc..cca2a2a3 100644
--- a/src/main/java/org/apache/maven/plugins/site/render/SiteMojo.java
+++ b/src/main/java/org/apache/maven/plugins/site/render/SiteMojo.java
@@ -30,6 +30,7 @@
import org.apache.maven.doxia.siterenderer.DocumentRenderer;
import org.apache.maven.doxia.siterenderer.DoxiaDocumentRenderer;
+import org.apache.maven.doxia.siterenderer.ParserConfigurator;
import org.apache.maven.doxia.siterenderer.RendererException;
import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
import org.apache.maven.doxia.tools.SiteTool;
@@ -43,6 +44,7 @@
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.reporting.exec.MavenReportExecution;
import org.apache.maven.shared.utils.logging.MessageBuilder;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
@@ -95,7 +97,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
checkInputEncoding();
- try {
+ try (ParserConfiguratorImpl parserConfigurator = createParserConfigurator()) {
List localesList = getLocales();
for (Locale locale : localesList) {
@@ -108,7 +110,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
File outputDirectory = getOutputDirectory(locale);
List reports =
generateReports ? getReports(outputDirectory) : Collections.emptyList();
- renderLocale(locale, reports, localesList, outputDirectory);
+ renderLocale(locale, reports, localesList, outputDirectory, parserConfigurator);
}
} catch (RendererException e) {
if (e.getCause() instanceof MavenReportException) {
@@ -118,13 +120,19 @@ public void execute() throws MojoExecutionException, MojoFailureException {
throw new MojoExecutionException("Failed to render site", e);
} catch (IOException e) {
throw new MojoExecutionException("Error during site generation", e);
+ } catch (ComponentLookupException e) {
+ throw new MojoExecutionException("Cannot lookup ComponentConfigurator for configuration of parsers", e);
}
}
private void renderLocale(
- Locale locale, List reports, List supportedLocales, File outputDirectory)
+ Locale locale,
+ List reports,
+ List supportedLocales,
+ File outputDirectory,
+ ParserConfigurator parserConfigurator)
throws IOException, RendererException, MojoFailureException, MojoExecutionException {
- SiteRenderingContext context = createSiteRenderingContext(locale);
+ SiteRenderingContext context = createSiteRenderingContext(locale, parserConfigurator);
context.addSiteLocales(supportedLocales);
context.setInputEncoding(getInputEncoding());
context.setOutputEncoding(getOutputEncoding());
diff --git a/src/main/java/org/apache/maven/plugins/site/run/SiteRunMojo.java b/src/main/java/org/apache/maven/plugins/site/run/SiteRunMojo.java
index 266909c4..a9af5cde 100644
--- a/src/main/java/org/apache/maven/plugins/site/run/SiteRunMojo.java
+++ b/src/main/java/org/apache/maven/plugins/site/run/SiteRunMojo.java
@@ -37,6 +37,7 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.plugins.site.render.AbstractSiteRenderingMojo;
+import org.apache.maven.plugins.site.render.ParserConfiguratorImpl;
import org.apache.maven.reporting.exec.MavenReportExecution;
import org.codehaus.plexus.util.IOUtil;
import org.eclipse.jetty.server.Server;
@@ -125,11 +126,11 @@ private WebAppContext createWebApplication() throws MojoExecutionException {
List localesList = getLocales();
webapp.setAttribute(DoxiaFilter.LOCALES_LIST_KEY, localesList);
- try {
+ try (ParserConfiguratorImpl parserConfigurator = createParserConfigurator()) {
Map i18nDoxiaContexts = new HashMap<>();
for (Locale locale : localesList) {
- SiteRenderingContext i18nContext = createSiteRenderingContext(locale);
+ SiteRenderingContext i18nContext = createSiteRenderingContext(locale, parserConfigurator);
i18nContext.setInputEncoding(getInputEncoding());
i18nContext.setOutputEncoding(getOutputEncoding());