/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xwiki.rendering.internal.configuration; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; import javax.inject.Singleton; import org.xwiki.component.annotation.Component; import org.xwiki.component.manager.ComponentLookupException; import org.xwiki.component.manager.ComponentManager; import org.xwiki.configuration.ConfigurationSource; import org.xwiki.rendering.configuration.ExtendedRenderingConfiguration; import org.xwiki.rendering.parser.ParseException; import org.xwiki.rendering.parser.Parser; import org.xwiki.rendering.syntax.Syntax; import org.xwiki.rendering.syntax.SyntaxFactory; import com.xpn.xwiki.CoreConfiguration; /** * Extended configuration options for the Rendering subsystem. * * @version $Id: 7dc9693f3bbc927abce1b7aa84846cc3b51840d5 $ * @since 8.2M1 */ @Component @Singleton public class DefaultExtendedRenderingConfiguration implements ExtendedRenderingConfiguration { /** * Prefix for configuration keys for the Rendering module. */ private static final String PREFIX = "rendering."; private static final String DISABLED_SYNTAXES_PROPERTY = "disabledSyntaxes"; /** * Defines from where to read the rendering configuration data. */ @Inject private ConfigurationSource configuration; @Inject @Named("rendering") private ConfigurationSource renderingConfiguration; @Inject @Named("xwikicfg") private ConfigurationSource xwikiCfgConfiguration; @Inject private CoreConfiguration coreConfiguration; @Inject private SyntaxFactory syntaxFactory; /** * Used to lookup parsers and renderers to discover available syntaxes. */ @Inject @Named("context") private Provider<ComponentManager> componentManagerProvider; @Override public int getImageWidthLimit() { return this.configuration.getProperty(PREFIX + "imageWidthLimit", -1); } @Override public int getImageHeightLimit() { return this.configuration.getProperty(PREFIX + "imageHeightLimit", -1); } @Override public boolean isImageDimensionsIncludedInImageURL() { return this.configuration.getProperty(PREFIX + "imageDimensionsIncludedInImageURL", true); } @Override public List<Syntax> getDisabledSyntaxes() { List<Syntax> disabledSyntaxes = new ArrayList<>(); // First, look in the document sources List<String> disabledSyntaxesAsStrings = this.renderingConfiguration.getProperty(DISABLED_SYNTAXES_PROPERTY); // If not found, look in the xwiki cfg source for a xwiki.rendering.syntaxes property if (disabledSyntaxesAsStrings == null || disabledSyntaxesAsStrings.isEmpty()) { List<Syntax> configuredSyntaxes = convertList(this.xwikiCfgConfiguration.getProperty("xwiki.rendering.syntaxes", List.class)); // If there's no such property, then only allow the default syntax. We do this since we don't want users to // see bundled syntaxes by default. We only want them to see automatically syntaxes installed thereafter by // the Extension Manager. if (configuredSyntaxes == null || configuredSyntaxes.isEmpty()) { disabledSyntaxes.addAll(computeDisabledSyntaxes( Collections.singletonList(this.coreConfiguration.getDefaultDocumentSyntax()))); } else { // Disable all syntaxes except those in xwiki.rendering.syntaxes disabledSyntaxes.addAll(computeDisabledSyntaxes(configuredSyntaxes)); } } else { // Convert into a list of Syntax objects disabledSyntaxes.addAll(convertList(disabledSyntaxesAsStrings)); } return disabledSyntaxes; } @Override public List<Syntax> getConfiguredSyntaxes() { List<Syntax> configuredSyntaxes = new ArrayList<>(); List<Syntax> disabledSyntaxes = getDisabledSyntaxes(); for (Syntax availablesyntax : getAvailableParserSyntaxes()) { if (!disabledSyntaxes.contains(availablesyntax)) { configuredSyntaxes.add(availablesyntax); } } return configuredSyntaxes; } private List<Syntax> convertList(List<String> syntaxesAsStrings) { if (syntaxesAsStrings == null) { return null; } List<Syntax> syntaxes = new ArrayList<>(); for (String syntaxAsString : syntaxesAsStrings) { try { syntaxes.add(this.syntaxFactory.createSyntaxFromIdString(syntaxAsString)); } catch (ParseException e) { throw new RuntimeException( String.format("Failed to convert [%s] into Syntax object", syntaxAsString), e); } } return syntaxes; } private List<Syntax> computeDisabledSyntaxes(List<Syntax> configuredSyntaxes) { List<Syntax> disabledSyntaxes = new ArrayList<>(); for (Syntax availableSyntax : getAvailableParserSyntaxes()) { if (!configuredSyntaxes.contains(availableSyntax)) { disabledSyntaxes.add(availableSyntax); } } return disabledSyntaxes; } /** * @return the list of syntaxes for which a Parser is available */ public List<Syntax> getAvailableParserSyntaxes() { List<Syntax> syntaxes = new ArrayList<>(); try { for (Parser parser : this.componentManagerProvider.get().<Parser>getInstanceList(Parser.class)) { syntaxes.add(parser.getSyntax()); } } catch (ComponentLookupException e) { // This shouldn't happen; if it does then it's critical throw new RuntimeException("Failed to lookup parsers", e); } return syntaxes; } }