You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by bo...@apache.org on 2020/12/02 18:10:35 UTC
[myfaces-tobago] branch master updated: TOBAGO-2060: Tobago should
be compatible with Spring Boot
This is an automated email from the ASF dual-hosted git repository.
bommel pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git
The following commit(s) were added to refs/heads/master by this push:
new fe0a62b TOBAGO-2060: Tobago should be compatible with Spring Boot
fe0a62b is described below
commit fe0a62b73b88084b9ea4ac841b822f55046cb03b
Author: Udo Schnurpfeil <ud...@irian.eu>
AuthorDate: Wed Dec 2 18:51:39 2020 +0100
TOBAGO-2060: Tobago should be compatible with Spring Boot
* Replacing CDI.current()
* Refactoring TobagoConfig and its initialization
---
.../apache/myfaces/tobago/config/TobagoConfig.java | 334 ++++++++++++++++---
.../myfaces/tobago/context/TobagoContext.java | 32 +-
.../tobago/facelets/TobagoComponentHandler.java | 10 +-
.../internal/config/TobagoConfigBuilder.java | 128 -------
.../tobago/internal/config/TobagoConfigImpl.java | 369 ---------------------
.../tobago/internal/config/TobagoConfigLoader.java | 110 ++++++
.../tobago/internal/config/TobagoConfigMerger.java | 113 +++++--
.../tobago/internal/config/TobagoConfigSorter.java | 11 +-
.../internal/renderkit/renderer/PageRenderer.java | 10 +-
.../myfaces/tobago/internal/util/ArrayUtils.java | 3 +
.../tobago/internal/util/AuthorizationHelper.java | 41 +--
.../tobago/lifecycle/SecretPhaseListener.java | 9 +-
.../org/apache/myfaces/tobago/webapp/Secret.java | 26 +-
.../SecretSessionListener.java} | 35 +-
.../src/main/resources/META-INF/web-fragment.xml | 3 +
.../internal/config/AbstractTobagoTestBase.java | 6 +-
.../config/TobagoConfigMergingUnitTest.java | 102 ++----
.../config/TobagoConfigSorterUnitTest.java | 66 ++--
18 files changed, 646 insertions(+), 762 deletions(-)
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java
index e7d0594..831eada 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/config/TobagoConfig.java
@@ -20,80 +20,338 @@
package org.apache.myfaces.tobago.config;
import org.apache.myfaces.tobago.context.Theme;
+import org.apache.myfaces.tobago.context.ThemeImpl;
+import org.apache.myfaces.tobago.exception.TobagoConfigurationException;
import org.apache.myfaces.tobago.internal.config.ContentSecurityPolicy;
import org.apache.myfaces.tobago.internal.config.SecurityAnnotation;
+import org.apache.myfaces.tobago.internal.config.TobagoConfigFragment;
+import org.apache.myfaces.tobago.internal.config.TobagoConfigLoader;
+import org.apache.myfaces.tobago.internal.config.TobagoConfigMerger;
+import org.apache.myfaces.tobago.internal.config.TobagoConfigSorter;
import org.apache.myfaces.tobago.sanitizer.Sanitizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.enterprise.inject.spi.CDI;
+import javax.faces.application.Application;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
-public abstract class TobagoConfig {
+public class TobagoConfig {
private static final Logger LOG = LoggerFactory.getLogger(TobagoConfig.class);
- /**
- * @deprecated Since 5.0.0. Please use CDI.
- */
- @Deprecated
public static final String TOBAGO_CONFIG = "org.apache.myfaces.tobago.config.TobagoConfig";
- /**
- * @deprecated Since 5.0.0. Please use CDI.
- */
- @Deprecated
+ private List<Theme> supportedThemes;
+ private List<String> supportedThemeNames;
+ private Theme defaultTheme;
+ private String defaultThemeName;
+ private Map<String, ThemeImpl> availableThemes;
+ private boolean createSessionSecret;
+ private boolean checkSessionSecret;
+ private boolean preventFrameAttacks;
+ private final ContentSecurityPolicy contentSecurityPolicy;
+ private SecurityAnnotation securityAnnotation;
+ private boolean setNosniffHeader;
+ private Map<String, String> defaultValidatorInfo;
+ private Sanitizer sanitizer;
+ private boolean decodeLineFeed;
+ private Map<String, String> mimeTypes;
+
+ private boolean locked = false;
+
public static TobagoConfig getInstance(final FacesContext facesContext) {
- TobagoConfig tobagoConfig = null;
- try {
- tobagoConfig = CDI.current().select(TobagoConfig.class).get();
- } catch (Exception e) {
- LOG.warn("No CDI!");
+ final Map<String, Object> applicationMap = facesContext.getExternalContext().getApplicationMap();
+
+ TobagoConfig tobagoConfig = (TobagoConfig) applicationMap.get(TOBAGO_CONFIG);
+ if (tobagoConfig != null) {
+ return tobagoConfig;
}
+
+ tobagoConfig = new TobagoConfig((ServletContext) facesContext.getExternalContext().getContext());
+ applicationMap.put(TOBAGO_CONFIG, tobagoConfig);
+
+ return tobagoConfig;
+ }
+
+ public static TobagoConfig getInstance(final ServletContext servletContext) {
+ TobagoConfig tobagoConfig = (TobagoConfig) servletContext.getAttribute(TOBAGO_CONFIG);
if (tobagoConfig != null) {
return tobagoConfig;
- } else {
- // XXX not nice: this happens while unit tests and whenever???
- return (TobagoConfig) facesContext.getExternalContext().getApplicationMap().get(TOBAGO_CONFIG);
}
+
+ tobagoConfig = new TobagoConfig(servletContext);
+ servletContext.setAttribute(TOBAGO_CONFIG, tobagoConfig);
+
+ return tobagoConfig;
}
/**
- * @deprecated Since 5.0.0. Please use CDI.
+ * @param servletContext From the container. If null, the WEB-INF/tobago-config.xml will be ignored.
+ * @param alternative Alternative tobago-config-files, only needed for testing.
*/
- @Deprecated
- public static TobagoConfig getInstance(final ServletContext servletContext) {
- return CDI.current().select(TobagoConfig.class).get();
+ public TobagoConfig(final ServletContext servletContext, final String... alternative) {
+
+ supportedThemeNames = new ArrayList<>();
+ supportedThemes = new ArrayList<>();
+ availableThemes = new HashMap<>();
+ createSessionSecret = true;
+ checkSessionSecret = true;
+ preventFrameAttacks = true;
+ setNosniffHeader = true;
+ securityAnnotation = SecurityAnnotation.disable;
+ decodeLineFeed = true;
+ contentSecurityPolicy = new ContentSecurityPolicy(ContentSecurityPolicy.Mode.OFF.getValue());
+ mimeTypes = new HashMap<>();
+
+ // internal
+ final List<TobagoConfigFragment> fragments = new ArrayList<>();
+
+ try {
+ TobagoConfigLoader.load(fragments, servletContext, alternative);
+ TobagoConfigSorter.sort(fragments);
+ TobagoConfigMerger.merge(fragments, this);
+ initDefaultValidatorInfo();
+ lock();
+//todo? servletContext.setAttribute(TobagoConfig.TOBAGO_CONFIG, this);
+ } catch (final Exception e) {
+ final String error = "Tobago can't be initialized! Application will not run correctly!";
+ LOG.error(error, e);
+ throw new TobagoConfigurationException(error, e);
+ }
}
- public abstract Theme getTheme(final String name);
+ /**
+ * Lock the configuration, so it cannot be modified any more.
+ */
+ public void lock() {
+ locked = true;
+ supportedThemes = Collections.unmodifiableList(supportedThemes);
+ for (final Theme theme : supportedThemes) {
+ ((ThemeImpl) theme).lock();
+ }
+ supportedThemeNames = Collections.unmodifiableList(supportedThemeNames);
+ availableThemes = Collections.unmodifiableMap(availableThemes);
+
+ contentSecurityPolicy.lock();
- public abstract List<Theme> getSupportedThemes();
+ mimeTypes = Collections.unmodifiableMap(mimeTypes);
+ }
- public abstract Theme getDefaultTheme();
+ private void checkUnlocked() throws IllegalStateException {
+ if (locked) {
+ throw new TobagoConfigurationException("The configuration must not be changed after initialization!");
+ }
+ }
- public abstract boolean isCreateSessionSecret();
+ public void addSupportedThemeName(final String name) {
+ checkUnlocked();
+ supportedThemeNames.add(name);
+ }
- public abstract boolean isCheckSessionSecret();
+ public List<String> getSupportedThemeNames() {
+ return supportedThemeNames;
+ }
- /**
- * @deprecated But needed to support frame security in IE11. Is replaced by CSP "frame-ancestors".
- */
- @Deprecated
- public abstract boolean isPreventFrameAttacks();
+ public Theme getTheme(final String name) {
+ if (name == null) {
+ LOG.debug("searching theme: null");
+ return defaultTheme;
+ }
+ if (defaultTheme != null && defaultTheme.getName().equals(name)) {
+ return defaultTheme;
+ }
+ for (final Theme theme : supportedThemes) {
+ if (theme.getName().equals(name)) {
+ return theme;
+ }
+ }
+ LOG.debug("searching theme '{}' not found. Using default: {}", name, defaultTheme);
+ return defaultTheme;
+ }
+
+ public void setDefaultThemeName(final String defaultThemeName) {
+ checkUnlocked();
+ this.defaultThemeName = defaultThemeName;
+ }
+
+ public String getDefaultThemeName() {
+ return defaultThemeName;
+ }
+
+ public List<Theme> getSupportedThemes() {
+ return supportedThemes;
+ }
+
+ public void setDefaultTheme(final Theme defaultTheme) {
+ this.defaultTheme = defaultTheme;
+ }
+
+ public Theme getDefaultTheme() {
+ return defaultTheme;
+ }
+
+ public void addAvailableTheme(final ThemeImpl availableTheme) {
+ checkUnlocked();
+ final String name = availableTheme.getName();
+ if (availableThemes.containsKey(name)) {
+ final ThemeImpl base = availableThemes.get(name);
+ availableThemes.put(name, ThemeImpl.merge(base, availableTheme));
+ } else {
+ availableThemes.put(name, availableTheme);
+ }
+ }
+
+ public Map<String, ThemeImpl> getAvailableThemes() {
+ return availableThemes;
+ }
+
+ public boolean isCreateSessionSecret() {
+ return createSessionSecret;
+ }
+
+ public void setCreateSessionSecret(final boolean createSessionSecret) {
+ checkUnlocked();
+ this.createSessionSecret = createSessionSecret;
+ }
+
+ public boolean isCheckSessionSecret() {
+ return checkSessionSecret;
+ }
+
+ public void setCheckSessionSecret(final boolean checkSessionSecret) {
+ checkUnlocked();
+ this.checkSessionSecret = checkSessionSecret;
+ }
+
+
+ public boolean isPreventFrameAttacks() {
+ return preventFrameAttacks;
+ }
+
+ public void setPreventFrameAttacks(final boolean preventFrameAttacks) {
+ checkUnlocked();
+ this.preventFrameAttacks = preventFrameAttacks;
+ }
+
+ public ContentSecurityPolicy getContentSecurityPolicy() {
+ return contentSecurityPolicy;
+ }
+
+ public boolean isSetNosniffHeader() {
+ return setNosniffHeader;
+ }
- public abstract ContentSecurityPolicy getContentSecurityPolicy();
+ public void setSetNosniffHeader(final boolean setNosniffHeader) {
+ checkUnlocked();
+ this.setNosniffHeader = setNosniffHeader;
+ }
+
+ public SecurityAnnotation getSecurityAnnotation() {
+ return securityAnnotation;
+ }
- public abstract boolean isSetNosniffHeader();
+ public void setSecurityAnnotation(final SecurityAnnotation securityAnnotation) {
+ checkUnlocked();
+ this.securityAnnotation = securityAnnotation;
+ }
- public abstract SecurityAnnotation getSecurityAnnotation();
+ public Map<String, String> getDefaultValidatorInfo() {
+ // TODO: if the startup hasn't found a FacesContext and Application, this may depend on the order of the listeners.
+ if (defaultValidatorInfo == null) {
+ initDefaultValidatorInfo();
+ }
+ return defaultValidatorInfo;
+ }
- public abstract Sanitizer getSanitizer();
+ public Sanitizer getSanitizer() {
+ return sanitizer;
+ }
- public abstract boolean isDecodeLineFeed();
+ public void setSanitizer(final Sanitizer sanitizer) {
+ checkUnlocked();
+ this.sanitizer = sanitizer;
+ }
- public abstract Map<String, String> getMimeTypes();
+ public boolean isDecodeLineFeed() {
+ return decodeLineFeed;
+ }
+
+ public void setDecodeLineFeed(final boolean decodeLineFeed) {
+ checkUnlocked();
+ this.decodeLineFeed = decodeLineFeed;
+ }
+
+ public Map<String, String> getMimeTypes() {
+ return mimeTypes;
+ }
+
+ private void initDefaultValidatorInfo() {
+ if (defaultValidatorInfo != null) {
+ checkUnlocked();
+ }
+ final FacesContext facesContext = FacesContext.getCurrentInstance();
+ if (facesContext != null) {
+ try {
+ final Application application = facesContext.getApplication();
+ final Map<String, String> map = application.getDefaultValidatorInfo();
+ if (map.size() > 0) {
+ defaultValidatorInfo = Collections.unmodifiableMap(map);
+ } else {
+ defaultValidatorInfo = Collections.emptyMap();
+ }
+ } catch (final Exception e) {
+ LOG.error("Can't initialize default validators (this happens with JBoss GateIn 3.6.0).", e);
+ defaultValidatorInfo = Collections.emptyMap();
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("TobagoConfigImpl{");
+ builder.append("\nsupportedThemes=[");
+ for (final Theme supportedTheme : supportedThemes) {
+ builder.append(supportedTheme.getName());
+ builder.append(", ");
+ }
+ builder.append("], \ndefaultTheme=");
+ builder.append(defaultTheme != null ? defaultTheme.getName() : null);
+ builder.append(", \navailableThemes=");
+ builder.append(availableThemes.keySet());
+ builder.append(", \ncreateSessionSecret=");
+ builder.append(createSessionSecret);
+ builder.append(", \ncheckSessionSecret=");
+ builder.append(checkSessionSecret);
+ builder.append(", \npreventFrameAttacks=");
+ builder.append(preventFrameAttacks);
+ builder.append(", \ncontentSecurityPolicy=");
+ builder.append(contentSecurityPolicy);
+ builder.append(", \nsecurityAnnotation=");
+ builder.append(securityAnnotation);
+ builder.append(", \nsetNosniffHeader=");
+ builder.append(setNosniffHeader);
+ builder.append(", \ndefaultValidatorInfo=");
+ builder.append(defaultValidatorInfo);
+ builder.append(", \nsanitizer=");
+ builder.append(sanitizer);
+ builder.append(", \ndecodeLineFeed=");
+ builder.append(decodeLineFeed);
+ // to see only different (ignore alternative names for the same theme)
+ builder.append(", \nthemes=");
+ final Set<Theme> all = new HashSet<>(availableThemes.values());
+ builder.append(all);
+ builder.append(", \nmimeTypes=");
+ builder.append(mimeTypes);
+ builder.append('}');
+ return builder.toString();
+ }
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoContext.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoContext.java
index 2cb7f76..6fa2858 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoContext.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/context/TobagoContext.java
@@ -21,7 +21,6 @@ package org.apache.myfaces.tobago.context;
import org.apache.myfaces.tobago.config.TobagoConfig;
import org.apache.myfaces.tobago.internal.util.CookieUtils;
-import org.apache.myfaces.tobago.util.VariableResolverUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,12 +28,12 @@ import javax.enterprise.context.RequestScoped;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
-import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.lang.invoke.MethodHandles;
import java.util.Locale;
+import java.util.Map;
import java.util.ResourceBundle;
@Named
@@ -45,7 +44,6 @@ public class TobagoContext implements Serializable {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- @Inject
private TobagoConfig tobagoConfig;
private Theme theme;
private UserAgent userAgent;
@@ -58,9 +56,10 @@ public class TobagoContext implements Serializable {
*/
@Deprecated
public ResourceBundle getResourceBundle() {
- final UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
+ final FacesContext facesContext = FacesContext.getCurrentInstance();
+ final UIViewRoot viewRoot = facesContext.getViewRoot();
final Locale locale = viewRoot != null
- ? viewRoot.getLocale() : FacesContext.getCurrentInstance().getApplication().getDefaultLocale();
+ ? viewRoot.getLocale() : facesContext.getApplication().getDefaultLocale();
return ResourceBundle.getBundle("tobagoResourceBundle", locale);
}
@@ -69,17 +68,17 @@ public class TobagoContext implements Serializable {
*/
@Deprecated
public ResourceBundle getMessageBundle() {
- final UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
+ final FacesContext facesContext = FacesContext.getCurrentInstance();
+ final UIViewRoot viewRoot = facesContext.getViewRoot();
final Locale locale = viewRoot != null
- ? viewRoot.getLocale() : FacesContext.getCurrentInstance().getApplication().getDefaultLocale();
+ ? viewRoot.getLocale() : facesContext.getApplication().getDefaultLocale();
return ResourceBundle.getBundle("org.apache.myfaces.tobago.context.TobagoMessage", locale);
}
- /**
- * @deprecated since 5.0.0. Please get/inject {@link TobagoConfig} directly by CDI.
- */
- @Deprecated
public TobagoConfig getTobagoConfig() {
+ if (tobagoConfig == null) {
+ tobagoConfig = TobagoConfig.getInstance(FacesContext.getCurrentInstance());
+ }
return tobagoConfig;
}
@@ -97,7 +96,7 @@ public class TobagoContext implements Serializable {
themeName = null;
}
- theme = tobagoConfig.getTheme(themeName);
+ theme = getTobagoConfig().getTheme(themeName);
if (LOG.isDebugEnabled()) {
LOG.debug("theme='{}'", theme.getName());
}
@@ -147,6 +146,13 @@ public class TobagoContext implements Serializable {
}
public static TobagoContext getInstance(final FacesContext facesContext) {
- return (TobagoContext) VariableResolverUtils.resolveVariable(facesContext, BEAN_NAME);
+ final Map<String, Object> requestMap = facesContext.getExternalContext().getRequestMap();
+ if (requestMap.containsKey(BEAN_NAME)) {
+ return (TobagoContext) requestMap.get(BEAN_NAME);
+ } else {
+ final TobagoContext tobagoContext = new TobagoContext();
+ requestMap.put(BEAN_NAME, tobagoContext);
+ return tobagoContext;
+ }
}
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/TobagoComponentHandler.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/TobagoComponentHandler.java
index 43939c8..65ab9d8 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/TobagoComponentHandler.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/TobagoComponentHandler.java
@@ -25,9 +25,7 @@ import org.apache.myfaces.tobago.config.TobagoConfig;
import org.apache.myfaces.tobago.event.SheetStateChangeSource;
import org.apache.myfaces.tobago.event.SortActionSource;
import org.apache.myfaces.tobago.event.TabChangeSource;
-import org.apache.myfaces.tobago.internal.config.TobagoConfigImpl;
-import javax.enterprise.inject.spi.CDI;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
@@ -78,8 +76,8 @@ public class TobagoComponentHandler extends ComponentHandler {
}
}
- private void addDefaultValidators(final FacesContext context, final EditableValueHolder component) {
- final TobagoConfigImpl tobagoConfig = (TobagoConfigImpl) CDI.current().select(TobagoConfig.class).get();
+ private void addDefaultValidators(final FacesContext facesContext, final EditableValueHolder component) {
+ final TobagoConfig tobagoConfig = TobagoConfig.getInstance(facesContext);
final Map<String, String> validatorInfoMap = tobagoConfig.getDefaultValidatorInfo();
if (validatorInfoMap.isEmpty()) {
return;
@@ -93,12 +91,12 @@ public class TobagoComponentHandler extends ComponentHandler {
}
validatorInfoMap.forEach((key, value) -> {
if (!classNames.contains(value)) {
- component.addValidator(context.getApplication().createValidator(key));
+ component.addValidator(facesContext.getApplication().createValidator(key));
}
});
} else {
for (final String next : validatorInfoMap.keySet()) {
- component.addValidator(context.getApplication().createValidator(next));
+ component.addValidator(facesContext.getApplication().createValidator(next));
}
}
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigBuilder.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigBuilder.java
deleted file mode 100644
index 5b3617c..0000000
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigBuilder.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.myfaces.tobago.internal.config;
-
-import org.apache.myfaces.tobago.config.TobagoConfig;
-import org.apache.myfaces.tobago.exception.TobagoConfigurationException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.inject.Produces;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-
-@Named
-@ApplicationScoped
-public class TobagoConfigBuilder {
-
- private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- private static final String WEB_INF_TOBAGO_CONFIG_XML = "WEB-INF/tobago-config.xml";
- private static final String META_INF_TOBAGO_CONFIG_XML = "META-INF/tobago-config.xml";
-
- @Inject
- private ServletContext servletContext;
-
- private TobagoConfigImpl tobagoConfig;
-
- @Produces
- public TobagoConfig buildTobagoConfig() {
- if (tobagoConfig == null) {
- init();
- }
- return tobagoConfig;
- }
-
- private void init() {
- final List<TobagoConfigFragment> configFragmentList = new ArrayList<>();
- try {
- configFromClasspath(configFragmentList);
- configFromWebInf(configFragmentList);
- final TobagoConfigSorter sorter = new TobagoConfigSorter(configFragmentList);
- final TobagoConfigMerger merger = new TobagoConfigMerger(sorter.topologicalSort());
- tobagoConfig = merger.merge();
- // prepare themes
- tobagoConfig.resolveThemes();
- tobagoConfig.initDefaultValidatorInfo();
- tobagoConfig.lock();
- servletContext.setAttribute(TobagoConfig.TOBAGO_CONFIG, tobagoConfig);
- } catch (final Exception e) {
- final String error = "Tobago can't be initialized! Application will not run correctly!";
- LOG.error(error, e);
- throw new TobagoConfigurationException(error, e);
- }
- }
-
- private void configFromWebInf(final List<TobagoConfigFragment> configFragmentList)
- throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
-
- final URL url = servletContext.getResource("/" + WEB_INF_TOBAGO_CONFIG_XML);
- if (url != null) {
- configFragmentList.add(new TobagoConfigParser().parse(url));
- }
- }
-
- private void configFromClasspath(final List<TobagoConfigFragment> configFragmentList)
- throws ServletException {
-
- try {
- if (LOG.isInfoEnabled()) {
- LOG.info("Searching for '" + META_INF_TOBAGO_CONFIG_XML + "'");
- }
- final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- final Enumeration<URL> urls = classLoader.getResources(META_INF_TOBAGO_CONFIG_XML);
- while (urls.hasMoreElements()) {
- final URL themeUrl = urls.nextElement();
- try {
- final TobagoConfigFragment fragment = new TobagoConfigParser().parse(themeUrl);
- fragment.setUrl(themeUrl);
- configFragmentList.add(fragment);
-
- // tomcat uses jar
- // weblogic uses zip
- // IBM WebSphere uses wsjar
- final String protocol = themeUrl.getProtocol();
- if (!"file".equals(protocol) && !"jar".equals(protocol)
- && !"zip".equals(protocol) && !"wsjar".equals(protocol)) {
- LOG.warn("Unknown protocol '" + themeUrl + "'");
- }
- } catch (final Exception e) {
- throw new Exception(e.getClass().getName() + " on themeUrl: " + themeUrl, e);
- }
- }
- } catch (final Exception e) {
- final String msg = "while loading ";
- LOG.error(msg, e);
- throw new ServletException(msg, e);
- }
- }
-}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigImpl.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigImpl.java
deleted file mode 100644
index c859d4b..0000000
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigImpl.java
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * 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.myfaces.tobago.internal.config;
-
-import org.apache.myfaces.tobago.config.TobagoConfig;
-import org.apache.myfaces.tobago.context.Theme;
-import org.apache.myfaces.tobago.context.ThemeImpl;
-import org.apache.myfaces.tobago.exception.TobagoConfigurationException;
-import org.apache.myfaces.tobago.sanitizer.Sanitizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.faces.application.Application;
-import javax.faces.context.FacesContext;
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * <p>
- * Implementation of the Tobago configuration.
- * </p>
- * <p>
- * All setters must are protected, so EL can't modify this config.
- * </p>
- */
-//@Named("tobagoConfig") // todo
-//@ApplicationScoped // todo
-public class TobagoConfigImpl extends TobagoConfig {
-
- private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- private List<Theme> supportedThemes;
- private List<String> supportedThemeNames;
- private Theme defaultTheme;
- private String defaultThemeName;
- private Map<String, ThemeImpl> availableThemes;
- private boolean createSessionSecret;
- private boolean checkSessionSecret;
- private boolean preventFrameAttacks;
- private final ContentSecurityPolicy contentSecurityPolicy;
- private SecurityAnnotation securityAnnotation;
- private boolean setNosniffHeader;
- private Map<String, String> defaultValidatorInfo;
- private Sanitizer sanitizer;
- private boolean decodeLineFeed;
- private Map<String, String> mimeTypes;
-
- private boolean locked = false;
-
- protected TobagoConfigImpl(String fixme) { // CDI workaround fixme
- supportedThemeNames = new ArrayList<>();
- supportedThemes = new ArrayList<>();
- availableThemes = new HashMap<>();
- createSessionSecret = true;
- checkSessionSecret = true;
- preventFrameAttacks = true;
- setNosniffHeader = true;
- securityAnnotation = SecurityAnnotation.disable;
- decodeLineFeed = true;
- contentSecurityPolicy = new ContentSecurityPolicy(ContentSecurityPolicy.Mode.OFF.getValue());
- mimeTypes = new HashMap<>();
- }
-
- /**
- * Lock the configuration, so it cannot be modified any more.
- */
- protected void lock() {
- locked = true;
- supportedThemes = Collections.unmodifiableList(supportedThemes);
- for (final Theme theme : supportedThemes) {
- ((ThemeImpl) theme).lock();
- }
- supportedThemeNames = Collections.unmodifiableList(supportedThemeNames);
- availableThemes = Collections.unmodifiableMap(availableThemes);
-
- contentSecurityPolicy.lock();
-
- mimeTypes = Collections.unmodifiableMap(mimeTypes);
- }
-
- private void checkUnlocked() throws IllegalStateException {
- if (locked) {
- throw new TobagoConfigurationException("The configuration must not be changed after initialization!");
- }
- }
-
- protected void addSupportedThemeName(final String name) {
- checkUnlocked();
- supportedThemeNames.add(name);
- }
-
- // TODO one init method
- protected void resolveThemes() {
- checkUnlocked();
-
- if (defaultThemeName != null) {
- defaultTheme = availableThemes.get(defaultThemeName);
- checkThemeIsAvailable(defaultThemeName, defaultTheme);
- if (LOG.isDebugEnabled()) {
- LOG.debug("name = '{}'", defaultThemeName);
- LOG.debug("defaultTheme = '{}'", defaultTheme);
- }
- } else {
- int deep = 0;
- for (final Map.Entry<String, ThemeImpl> entry : availableThemes.entrySet()) {
- final Theme theme = entry.getValue();
- if (theme.getFallbackList().size() > deep) {
- defaultTheme = theme;
- deep = theme.getFallbackList().size();
- }
- }
- if (defaultTheme == null) {
- final String error = "Did not found any theme! "
- + "Please ensure you have a tobago-config.xml with a theme-definition in your "
- + "theme JAR. Please add a theme JAR to your classpath. Usually "
- + "tobago-theme-standard.jar in WEB-INF/lib";
- LOG.error(error);
- throw new TobagoConfigurationException(error);
- } else {
- if (LOG.isInfoEnabled()) {
- LOG.info("Using default Theme {}", defaultTheme.getName());
- }
- }
- }
- if (!supportedThemeNames.isEmpty()) {
- for (final String name : supportedThemeNames) {
- final Theme theme = availableThemes.get(name);
- checkThemeIsAvailable(name, theme);
- supportedThemes.add(theme);
- if (LOG.isDebugEnabled()) {
- LOG.debug("name = '{}'", name);
- LOG.debug("supportedThemes.last() = '{}'", supportedThemes.get(supportedThemes.size() - 1));
- }
- }
- }
- }
-
- private void checkThemeIsAvailable(final String name, final Theme theme) {
- if (theme == null) {
- final String error = "Theme not found! name: '" + name + "'. "
- + "Please ensure you have a tobago-config.xml with a theme-definition in your "
- + "theme JAR. Found the following themes: " + availableThemes.keySet();
- LOG.error(error);
- throw new TobagoConfigurationException(error);
- }
- }
-
- @Override
- public Theme getTheme(final String name) {
- if (name == null) {
- LOG.debug("searching theme: null");
- return defaultTheme;
- }
- if (defaultTheme != null && defaultTheme.getName().equals(name)) {
- return defaultTheme;
- }
- for (final Theme theme : supportedThemes) {
- if (theme.getName().equals(name)) {
- return theme;
- }
- }
- LOG.debug("searching theme '{}' not found. Using default: {}", name, defaultTheme);
- return defaultTheme;
- }
-
- protected void setDefaultThemeName(final String defaultThemeName) {
- checkUnlocked();
- this.defaultThemeName = defaultThemeName;
- }
-
- @Override
- public List<Theme> getSupportedThemes() {
- return supportedThemes;
- }
-
- @Override
- public Theme getDefaultTheme() {
- return defaultTheme;
- }
-
- protected void addAvailableTheme(final ThemeImpl availableTheme) {
- checkUnlocked();
- final String name = availableTheme.getName();
- if (availableThemes.containsKey(name)) {
- final ThemeImpl base = availableThemes.get(name);
- availableThemes.put(name, ThemeImpl.merge(base, availableTheme));
- } else {
- availableThemes.put(name, availableTheme);
- }
- }
-
- public Map<String, ThemeImpl> getAvailableThemes() {
- return availableThemes;
- }
-
- protected synchronized void initDefaultValidatorInfo() {
- if (defaultValidatorInfo != null) {
- checkUnlocked();
- }
- final FacesContext facesContext = FacesContext.getCurrentInstance();
- if (facesContext != null) {
- try {
- final Application application = facesContext.getApplication();
- final Map<String, String> map = application.getDefaultValidatorInfo();
- if (map.size() > 0) {
- defaultValidatorInfo = Collections.unmodifiableMap(map);
- } else {
- defaultValidatorInfo = Collections.emptyMap();
- }
- } catch (final Exception e) {
- LOG.error("Can't initialize default validators (this happens with JBoss GateIn 3.6.0).", e);
- defaultValidatorInfo = Collections.emptyMap();
- }
- }
- }
-
- @Override
- public boolean isCreateSessionSecret() {
- return createSessionSecret;
- }
-
- protected void setCreateSessionSecret(final boolean createSessionSecret) {
- checkUnlocked();
- this.createSessionSecret = createSessionSecret;
- }
-
- @Override
- public boolean isCheckSessionSecret() {
- return checkSessionSecret;
- }
-
- protected void setCheckSessionSecret(final boolean checkSessionSecret) {
- checkUnlocked();
- this.checkSessionSecret = checkSessionSecret;
- }
-
-
- @Override
- public boolean isPreventFrameAttacks() {
- return preventFrameAttacks;
- }
-
- protected void setPreventFrameAttacks(final boolean preventFrameAttacks) {
- checkUnlocked();
- this.preventFrameAttacks = preventFrameAttacks;
- }
-
- @Override
- public ContentSecurityPolicy getContentSecurityPolicy() {
- return contentSecurityPolicy;
- }
-
- @Override
- public boolean isSetNosniffHeader() {
- return setNosniffHeader;
- }
-
- protected void setSetNosniffHeader(final boolean setNosniffHeader) {
- checkUnlocked();
- this.setNosniffHeader = setNosniffHeader;
- }
-
- @Override
- public SecurityAnnotation getSecurityAnnotation() {
- return securityAnnotation;
- }
-
- public void setSecurityAnnotation(final SecurityAnnotation securityAnnotation) {
- checkUnlocked();
- this.securityAnnotation = securityAnnotation;
- }
-
- public Map<String, String> getDefaultValidatorInfo() {
- // TODO: if the startup hasn't found a FacesContext and Application, this may depend on the order of the listeners.
- if (defaultValidatorInfo == null) {
- initDefaultValidatorInfo();
- }
- return defaultValidatorInfo;
- }
-
- @Override
- public Sanitizer getSanitizer() {
- return sanitizer;
- }
-
- protected void setSanitizer(final Sanitizer sanitizer) {
- checkUnlocked();
- this.sanitizer = sanitizer;
- }
-
- @Override
- public boolean isDecodeLineFeed() {
- return decodeLineFeed;
- }
-
- public void setDecodeLineFeed(final boolean decodeLineFeed) {
- checkUnlocked();
- this.decodeLineFeed = decodeLineFeed;
- }
-
- @Override
- public Map<String, String> getMimeTypes() {
- return mimeTypes;
- }
-
- @Override
- public String toString() {
- final StringBuilder builder = new StringBuilder();
- builder.append("TobagoConfigImpl{");
- builder.append("\nsupportedThemes=[");
- for (final Theme supportedTheme : supportedThemes) {
- builder.append(supportedTheme.getName());
- builder.append(", ");
- }
- builder.append("], \ndefaultTheme=");
- builder.append(defaultTheme != null ? defaultTheme.getName() : null);
- builder.append(", \navailableThemes=");
- builder.append(availableThemes.keySet());
- builder.append(", \ncreateSessionSecret=");
- builder.append(createSessionSecret);
- builder.append(", \ncheckSessionSecret=");
- builder.append(checkSessionSecret);
- builder.append(", \npreventFrameAttacks=");
- builder.append(preventFrameAttacks);
- builder.append(", \ncontentSecurityPolicy=");
- builder.append(contentSecurityPolicy);
- builder.append(", \nsecurityAnnotation=");
- builder.append(securityAnnotation);
- builder.append(", \nsetNosniffHeader=");
- builder.append(setNosniffHeader);
- builder.append(", \ndefaultValidatorInfo=");
- builder.append(defaultValidatorInfo);
- builder.append(", \nsanitizer=");
- builder.append(sanitizer);
- builder.append(", \ndecodeLineFeed=");
- builder.append(decodeLineFeed);
- // to see only different (ignore alternative names for the same theme)
- builder.append(", \nthemes=");
- final Set<Theme> all = new HashSet<>(availableThemes.values());
- builder.append(all);
- builder.append(", \nmimeTypes=");
- builder.append(mimeTypes);
- builder.append('}');
- return builder.toString();
- }
-}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigLoader.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigLoader.java
new file mode 100644
index 0000000..7291fa2
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigLoader.java
@@ -0,0 +1,110 @@
+/*
+ * 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.myfaces.tobago.internal.config;
+
+import org.apache.myfaces.tobago.internal.util.ArrayUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.List;
+
+public class TobagoConfigLoader {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+ private static final String WEB_INF_TOBAGO_CONFIG_XML = "/WEB-INF/tobago-config.xml";
+ private static final String[] META_INF_TOBAGO_CONFIG_XML = {"META-INF/tobago-config.xml"};
+
+ private TobagoConfigLoader() {
+ }
+
+ public static void load(
+ final List<TobagoConfigFragment> fragments, final ServletContext servletContext, final String... alternative)
+ throws URISyntaxException, SAXException, ParserConfigurationException, IOException, ServletException {
+
+ TobagoConfigLoader loader = new TobagoConfigLoader();
+ loader.loadFromWebInf(fragments, servletContext);
+ loader.loadFromClasspath(fragments, alternative);
+ }
+
+ private void loadFromWebInf(
+ final List<TobagoConfigFragment> configFragmentList, final ServletContext servletContext)
+ throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
+
+ if (servletContext != null) {
+ final URL url = servletContext.getResource(WEB_INF_TOBAGO_CONFIG_XML);
+ if (url != null) {
+ configFragmentList.add(new TobagoConfigParser().parse(url));
+ }
+ } else {
+ LOG.warn("No ServletContext to look for files in {}", WEB_INF_TOBAGO_CONFIG_XML);
+ }
+ }
+
+ private void loadFromClasspath(final List<TobagoConfigFragment> configFragmentList, final String... alternative)
+ throws ServletException {
+
+ final String[] configFiles;
+ if (ArrayUtils.isEmpty(alternative)) {
+ configFiles = META_INF_TOBAGO_CONFIG_XML;
+ } else {
+ configFiles = alternative;
+ }
+
+ try {
+ final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ for (String configFile : configFiles) {
+ final Enumeration<URL> urls = classLoader.getResources(configFile);
+ while (urls.hasMoreElements()) {
+ final URL themeUrl = urls.nextElement();
+ try {
+ final TobagoConfigFragment fragment = new TobagoConfigParser().parse(themeUrl);
+ fragment.setUrl(themeUrl);
+ configFragmentList.add(fragment);
+
+ // tomcat uses jar
+ // weblogic uses zip
+ // IBM WebSphere uses wsjar
+ final String protocol = themeUrl.getProtocol();
+ if (!"file".equals(protocol) && !"jar".equals(protocol)
+ && !"zip".equals(protocol) && !"wsjar".equals(protocol)) {
+ LOG.warn("Unknown protocol '" + themeUrl + "'");
+ }
+ } catch (final Exception e) {
+ throw new Exception(e.getClass().getName() + " on themeUrl: " + themeUrl, e);
+ }
+ }
+ }
+ } catch (final Exception e) {
+ final String msg = "while loading ";
+ LOG.error(msg, e);
+ throw new ServletException(msg, e);
+ }
+ }
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigMerger.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigMerger.java
index e28e389..9182f40 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigMerger.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigMerger.java
@@ -19,7 +19,10 @@
package org.apache.myfaces.tobago.internal.config;
+import org.apache.myfaces.tobago.config.TobagoConfig;
+import org.apache.myfaces.tobago.context.Theme;
import org.apache.myfaces.tobago.context.ThemeImpl;
+import org.apache.myfaces.tobago.exception.TobagoConfigurationException;
import org.apache.myfaces.tobago.sanitizer.IgnoringSanitizer;
import org.apache.myfaces.tobago.sanitizer.JsoupSanitizer;
import org.apache.myfaces.tobago.sanitizer.Sanitizer;
@@ -35,56 +38,62 @@ public class TobagoConfigMerger {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- private final List<TobagoConfigFragment> list;
+ private final List<TobagoConfigFragment> fragments;
+ private final TobagoConfig tobagoConfig;
- public TobagoConfigMerger(final List<TobagoConfigFragment> list) {
- this.list = list;
+ private TobagoConfigMerger(final List<TobagoConfigFragment> fragments, final TobagoConfig tobagoConfig) {
+ this.fragments = fragments;
+ this.tobagoConfig = tobagoConfig;
}
- public TobagoConfigImpl merge() {
+ public static void merge(final List<TobagoConfigFragment> fragments, final TobagoConfig tobagoConfig) {
+ final TobagoConfigMerger merger = new TobagoConfigMerger(fragments, tobagoConfig);
+ merger.merge();
+ merger.resolveThemes();
+ }
- final TobagoConfigImpl result = new TobagoConfigImpl("fixme"); // fixme workaround
+ private void merge() {
// default sanitizer
String sanitizerClass = JsoupSanitizer.class.getName();
Properties sanitizerProperties = new Properties();
sanitizerProperties.setProperty("whitelist", "relaxed");
- for (TobagoConfigFragment fragment : list) {
+ for (TobagoConfigFragment fragment : fragments) {
// default theme
final String defaultTheme = fragment.getDefaultThemeName();
if (defaultTheme != null) {
- result.setDefaultThemeName(defaultTheme);
+ tobagoConfig.setDefaultThemeName(defaultTheme);
}
// supported themes
for (final String supported : fragment.getSupportedThemeNames()) {
- result.addSupportedThemeName(supported);
+ tobagoConfig.addSupportedThemeName(supported);
}
// session secret
if (fragment.getCreateSessionSecret() != null) {
- result.setCreateSessionSecret(fragment.getCreateSessionSecret());
+ tobagoConfig.setCreateSessionSecret(fragment.getCreateSessionSecret());
}
if (fragment.getCheckSessionSecret() != null) {
- result.setCheckSessionSecret(fragment.getCheckSessionSecret());
+ tobagoConfig.setCheckSessionSecret(fragment.getCheckSessionSecret());
}
if (fragment.getPreventFrameAttacks() != null) {
- result.setPreventFrameAttacks(fragment.getPreventFrameAttacks());
+ tobagoConfig.setPreventFrameAttacks(fragment.getPreventFrameAttacks());
}
if (fragment.getContentSecurityPolicy() != null) {
- result.getContentSecurityPolicy().merge(fragment.getContentSecurityPolicy());
+ tobagoConfig.getContentSecurityPolicy().merge(fragment.getContentSecurityPolicy());
}
if (fragment.getSecurityAnnotation() != null) {
- result.setSecurityAnnotation(fragment.getSecurityAnnotation());
+ tobagoConfig.setSecurityAnnotation(fragment.getSecurityAnnotation());
}
if (fragment.getSetNosniffHeader() != null) {
- result.setSetNosniffHeader(fragment.getSetNosniffHeader());
+ tobagoConfig.setSetNosniffHeader(fragment.getSetNosniffHeader());
}
if (fragment.getSanitizerClass() != null) {
@@ -93,39 +102,37 @@ public class TobagoConfigMerger {
}
if (fragment.getDecodeLineFeed() != null) {
- result.setDecodeLineFeed(fragment.getDecodeLineFeed());
+ tobagoConfig.setDecodeLineFeed(fragment.getDecodeLineFeed());
}
// theme definition
for (final ThemeImpl theme : fragment.getThemeDefinitions()) {
- result.addAvailableTheme(theme);
+ tobagoConfig.addAvailableTheme(theme);
}
// url
// todo???
- final Map<String, String> mimeTypes = result.getMimeTypes();
+ final Map<String, String> mimeTypes = tobagoConfig.getMimeTypes();
for (final Map.Entry<String, String> entry : fragment.getMimeTypes().entrySet()) {
mimeTypes.put(entry.getKey(), entry.getValue());
}
}
- resolveThemes(result.getAvailableThemes());
+ resolveThemes(tobagoConfig.getAvailableThemes());
if (sanitizerClass != null) {
try {
final Class<? extends Sanitizer> aClass = Class.forName(sanitizerClass).asSubclass(Sanitizer.class);
final Sanitizer sanitizer = aClass.newInstance();
sanitizer.setProperties(sanitizerProperties);
- result.setSanitizer(sanitizer);
+ tobagoConfig.setSanitizer(sanitizer);
} catch (final Exception e) {
LOG.error("Can't create sanitizer: '" + sanitizerClass + "'", e);
- result.setSanitizer(new IgnoringSanitizer());
+ tobagoConfig.setSanitizer(new IgnoringSanitizer());
}
}
-
- return result;
}
private void resolveThemes(final Map<String, ThemeImpl> map) {
@@ -145,4 +152,66 @@ public class TobagoConfigMerger {
}
}
+ private void resolveThemes() {
+
+ final Map<String, ThemeImpl> availableThemes = tobagoConfig.getAvailableThemes();
+
+ if (tobagoConfig.getDefaultThemeName() != null) {
+ final String defaultThemeName = tobagoConfig.getDefaultThemeName();
+ final ThemeImpl defaultTheme = availableThemes.get(defaultThemeName);
+ tobagoConfig.setDefaultTheme(defaultTheme);
+ checkThemeIsAvailable(defaultThemeName, defaultTheme, availableThemes);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("name = '{}'", defaultThemeName);
+ LOG.debug("defaultTheme = '{}'", defaultTheme);
+ }
+ } else {
+ int deep = 0;
+ Theme defaultTheme = null;
+ for (final Map.Entry<String, ThemeImpl> entry : availableThemes.entrySet()) {
+ final Theme theme = entry.getValue();
+ if (theme.getFallbackList().size() > deep) {
+ defaultTheme = theme;
+ deep = theme.getFallbackList().size();
+ }
+ }
+ if (defaultTheme == null) {
+ final String error = "Did not found any theme! "
+ + "Please ensure you have a tobago-config.xml with a theme-definition in your "
+ + "theme JAR. Please add a theme JAR to your classpath. Usually "
+ + "tobago-theme-standard.jar in WEB-INF/lib";
+ LOG.error(error);
+ throw new TobagoConfigurationException(error);
+ } else {
+ tobagoConfig.setDefaultTheme(defaultTheme);
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Using default Theme {}", defaultTheme.getName());
+ }
+ }
+ }
+ if (!tobagoConfig.getSupportedThemeNames().isEmpty()) {
+ for (final String name : tobagoConfig.getSupportedThemeNames()) {
+ final Theme theme = availableThemes.get(name);
+ checkThemeIsAvailable(name, theme, availableThemes);
+ tobagoConfig.getSupportedThemes().add(theme);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("name = '{}'", name);
+ LOG.debug("last added theme = '{}'", theme);
+ }
+ }
+ }
+ }
+
+ private void checkThemeIsAvailable(
+ final String name, final Theme theme, final Map<String, ThemeImpl>availableThemes) {
+ if (theme == null) {
+ final String error = "Theme not found! name: '" + name + "'. "
+ + "Please ensure you have a tobago-config.xml with a theme-definition in your "
+ + "theme JAR. Found the following themes: " + availableThemes.keySet();
+ LOG.error(error);
+ throw new TobagoConfigurationException(error);
+ }
+ }
+
+
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigSorter.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigSorter.java
index b84e3b4..8c1bc75 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigSorter.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/config/TobagoConfigSorter.java
@@ -32,7 +32,14 @@ public class TobagoConfigSorter {
private final List<Vertex> vertices = new ArrayList<>();
- public TobagoConfigSorter(final List<TobagoConfigFragment> fragmentList) {
+ public static void sort(List<TobagoConfigFragment> fragments) {
+ TobagoConfigSorter sorter = new TobagoConfigSorter(fragments);
+ final List<TobagoConfigFragment> sorted = sorter.topologicalSort();
+ fragments.clear();
+ fragments.addAll(sorted);
+ }
+
+ private TobagoConfigSorter(final List<TobagoConfigFragment> fragmentList) {
for (TobagoConfigFragment tobagoConfigFragment : fragmentList) {
vertices.add(new Vertex(tobagoConfigFragment));
}
@@ -43,7 +50,7 @@ public class TobagoConfigSorter {
*
* @throws IllegalStateException When detecting a cycle.
*/
- public List<TobagoConfigFragment> topologicalSort() {
+ private List<TobagoConfigFragment> topologicalSort() {
createEdges();
checkCycles();
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
index d5ed108..e641318 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
@@ -54,7 +54,6 @@ import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.enterprise.inject.spi.CDI;
import javax.faces.application.Application;
import javax.faces.application.ProjectStage;
import javax.faces.application.ViewHandler;
@@ -105,8 +104,8 @@ public class PageRenderer<T extends AbstractUIPage> extends RendererBase<T> {
@Override
public void encodeBeginInternal(final FacesContext facesContext, final T component) throws IOException {
- final TobagoConfig tobagoConfig = CDI.current().select(TobagoConfig.class).get(); // todo: may inject
- final TobagoContext tobagoContext = CDI.current().select(TobagoContext.class).get(); // todo: may inject
+ final TobagoConfig tobagoConfig = TobagoConfig.getInstance(facesContext);
+ final TobagoContext tobagoContext = TobagoContext.getInstance(facesContext);
if (tobagoContext.getFocusId() == null && !StringUtils.isBlank(component.getFocusId())) {
tobagoContext.setFocusId(component.getFocusId());
@@ -290,13 +289,12 @@ public class PageRenderer<T extends AbstractUIPage> extends RendererBase<T> {
writer.endElement(HtmlElements.TOBAGO_FOCUS);
if (tobagoConfig.isCheckSessionSecret()) {
+ final Secret secret = Secret.getInstance(facesContext);
writer.startElement(HtmlElements.INPUT);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
writer.writeAttribute(HtmlAttributes.NAME, Secret.KEY, false);
writer.writeAttribute(HtmlAttributes.ID, Secret.KEY, false);
-// final Object session = facesContext.getExternalContext().getSession(true);
- final Secret secret = CDI.current().select(Secret.class).get();
- secret.encode(writer);
+ writer.writeAttribute(HtmlAttributes.VALUE, secret.getSecret(), false);
writer.endElement(HtmlElements.INPUT);
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ArrayUtils.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ArrayUtils.java
index 5bd40f3..4202b42 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ArrayUtils.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ArrayUtils.java
@@ -47,4 +47,7 @@ public class ArrayUtils {
return false;
}
+ public static boolean isEmpty(final String[] array) {
+ return array == null || array.length == 0;
+ }
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/AuthorizationHelper.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/AuthorizationHelper.java
index 678b3ab..87a3318 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/AuthorizationHelper.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/AuthorizationHelper.java
@@ -25,10 +25,9 @@ import org.slf4j.LoggerFactory;
import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
+import javax.el.ELContext;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.CDI;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import java.lang.annotation.Annotation;
@@ -67,33 +66,15 @@ public class AuthorizationHelper {
private final Map<String, Object> cache = new ConcurrentHashMap<>();
- private final BeanManager beanManager;
-
- public AuthorizationHelper() {
- beanManager = CDI.current().getBeanManager();
- LOG.info("Using bean manager: '{}'", beanManager);
- }
-
public static AuthorizationHelper getInstance(final FacesContext facesContext) {
+ final ELContext elContext = facesContext.getELContext();
return (AuthorizationHelper)
- facesContext.getELContext().getELResolver().getValue(facesContext.getELContext(), null, AUTHORIZATION_HELPER);
- }
-
- Object getObject(String beanString) {
- Object bean = null;
- for (final Bean<?> entry : beanManager.getBeans(beanString)) {
- if (bean == null) {
- bean = entry;
- } else {
- LOG.warn("Bean name ambiguous: '{}'", beanString);
- }
- }
- return bean;
+ elContext.getELResolver().getValue(elContext, null, AUTHORIZATION_HELPER);
}
public boolean isAuthorized(final FacesContext facesContext, final String expression) {
- final Annotation securityAnnotation = getSecurityAnnotation(expression);
+ final Annotation securityAnnotation = getSecurityAnnotation(facesContext, expression);
if (securityAnnotation == null) {
return true;
}
@@ -126,7 +107,7 @@ public class AuthorizationHelper {
return true;
}
- private Annotation getSecurityAnnotation(final String expression) {
+ private Annotation getSecurityAnnotation(final FacesContext facesContext, final String expression) {
if (cache.containsKey(expression)) {
final Object obj = cache.get(expression);
if (obj instanceof Annotation) {
@@ -140,7 +121,9 @@ public class AuthorizationHelper {
final String beanString = matcher.group(1);
final String methodString = matcher.group(2);
- final Object bean = getObject(beanString);
+ final ELContext elContext = facesContext.getELContext();
+ final Object bean = elContext
+ .getELResolver().getValue(elContext, null, beanString);
if (bean != null) {
// try first from method
final List<Method> methods = findMethods(bean, methodString);
@@ -188,7 +171,13 @@ public class AuthorizationHelper {
}
private List<Method> findMethods(final Object bean, final String name) {
- final Class clazz = ((Bean) bean).getBeanClass();
+ final Class clazz;
+ if (bean instanceof Bean) {
+ clazz = ((Bean) bean).getBeanClass();
+ } else {
+ // XXX check if this works correctly with spring.
+ clazz = bean.getClass();
+ }
final Method[] methods = clazz.getMethods();
final List<Method> result = new ArrayList<>();
for (final Method method : methods) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/lifecycle/SecretPhaseListener.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/lifecycle/SecretPhaseListener.java
index 1d6d9ae..019308f 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/lifecycle/SecretPhaseListener.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/lifecycle/SecretPhaseListener.java
@@ -24,7 +24,6 @@ import org.apache.myfaces.tobago.webapp.Secret;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.enterprise.inject.spi.CDI;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
@@ -39,7 +38,7 @@ public class SecretPhaseListener implements PhaseListener {
@Override
public void afterPhase(final PhaseEvent event) {
final FacesContext facesContext = event.getFacesContext();
- final TobagoConfig tobagoConfig = CDI.current().select(TobagoConfig.class).get();
+ final TobagoConfig tobagoConfig = TobagoConfig.getInstance(facesContext);
if (!facesContext.getResponseComplete()
&& facesContext.isPostback()
@@ -58,9 +57,9 @@ public class SecretPhaseListener implements PhaseListener {
*/
private boolean check(final FacesContext facesContext) {
final Map<String, String> requestParameterMap = facesContext.getExternalContext().getRequestParameterMap();
- final String fromRequest = requestParameterMap.get(Secret.KEY);
- final Secret secret = CDI.current().select(Secret.class).get();
- return secret.check(fromRequest);
+ final String secretFromRequest = requestParameterMap.get(Secret.KEY);
+ final Secret secret = Secret.getInstance(facesContext);
+ return secret.check(secretFromRequest);
}
@Override
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/Secret.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/Secret.java
index 995a4a7..dba57c0 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/Secret.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/Secret.java
@@ -20,16 +20,12 @@
package org.apache.myfaces.tobago.webapp;
import org.apache.myfaces.tobago.internal.util.RandomUtils;
-import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
-import javax.enterprise.context.SessionScoped;
-import javax.inject.Named;
-import java.io.IOException;
+import javax.faces.context.FacesContext;
+import javax.servlet.http.HttpSession;
import java.io.Serializable;
-@Named
-@SessionScoped
-public class Secret implements Serializable {
+public final class Secret implements Serializable {
private static final long serialVersionUID = 1L;
@@ -41,11 +37,23 @@ public class Secret implements Serializable {
secret = RandomUtils.nextString();
}
+ public static Secret getInstance(final FacesContext facesContext) {
+ return (Secret) facesContext.getExternalContext().getSessionMap().get(Secret.KEY);
+ }
+
+ /**
+ * Create a secret attribute in the session.
+ * Should usually be called in a {@link javax.servlet.http.HttpSessionListener}.
+ */
+ public static void create(final HttpSession session) {
+ session.setAttribute(Secret.KEY, new Secret());
+ }
+
public boolean check(final String test) {
return secret.equals(test);
}
- public void encode(TobagoResponseWriter writer) throws IOException {
- writer.writeAttribute(HtmlAttributes.VALUE, this.secret, false);
+ public String getSecret() {
+ return secret;
}
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ArrayUtils.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/SecretSessionListener.java
similarity index 55%
copy from tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ArrayUtils.java
copy to tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/SecretSessionListener.java
index 5bd40f3..79d4b0d 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/ArrayUtils.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/webapp/SecretSessionListener.java
@@ -17,34 +17,23 @@
* under the License.
*/
-package org.apache.myfaces.tobago.internal.util;
+package org.apache.myfaces.tobago.webapp;
-public class ArrayUtils {
+import org.apache.myfaces.tobago.config.TobagoConfig;
- public static final String[] EMPTY_STRING_ARRAY = new String[0];
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
- public static <T> boolean contains(final T[] list, final T value) {
- if (list == null) {
- return false;
- }
- for (final T element : list) {
- if (element == value || element != null && element.equals(value)) {
- return true;
- }
- }
- return false;
- }
+public class SecretSessionListener implements HttpSessionListener {
- public static boolean contains(final int[] list, final int value) {
- if (list == null) {
- return false;
+ @Override
+ public void sessionCreated(final HttpSessionEvent sessionEvent) {
+ if (TobagoConfig.getInstance(sessionEvent.getSession().getServletContext()).isCreateSessionSecret()) {
+ Secret.create(sessionEvent.getSession());
}
- for (final int element : list) {
- if (element == value) {
- return true;
- }
- }
- return false;
}
+ @Override
+ public void sessionDestroyed(final HttpSessionEvent sessionEvent) {
+ }
}
diff --git a/tobago-core/src/main/resources/META-INF/web-fragment.xml b/tobago-core/src/main/resources/META-INF/web-fragment.xml
index 2ac0ab5..0543a4d 100644
--- a/tobago-core/src/main/resources/META-INF/web-fragment.xml
+++ b/tobago-core/src/main/resources/META-INF/web-fragment.xml
@@ -29,5 +29,8 @@
<listener>
<listener-class>org.apache.myfaces.tobago.webapp.TobagoServletContextListener</listener-class>
</listener>
+ <listener>
+ <listener-class>org.apache.myfaces.tobago.webapp.SecretSessionListener</listener-class>
+ </listener>
</web-fragment>
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/AbstractTobagoTestBase.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/AbstractTobagoTestBase.java
index 90919d1..76518b9 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/AbstractTobagoTestBase.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/AbstractTobagoTestBase.java
@@ -48,6 +48,7 @@ import org.apache.myfaces.tobago.component.UISelectOneRadio;
import org.apache.myfaces.tobago.component.UISeparator;
import org.apache.myfaces.tobago.component.UIStyle;
import org.apache.myfaces.tobago.component.UITextarea;
+import org.apache.myfaces.tobago.config.TobagoConfig;
import org.apache.myfaces.tobago.context.TobagoContext;
import org.apache.myfaces.tobago.internal.behavior.EventBehavior;
import org.apache.myfaces.tobago.internal.renderkit.renderer.BadgeRenderer;
@@ -79,6 +80,7 @@ import org.junit.jupiter.api.BeforeEach;
import javax.faces.component.behavior.AjaxBehavior;
import javax.faces.render.RenderKit;
+import javax.servlet.ServletContext;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
@@ -115,8 +117,8 @@ public abstract class AbstractTobagoTestBase extends AbstractJsfTestCase {
getFacesContext().setResponseWriter(new HtmlResponseWriter(stringWriter, "", StandardCharsets.UTF_8));
// Tobago specific extensions
- final TobagoConfigImpl tobagoConfig = TobagoConfigMergingUnitTest.load("tobago-config-for-unit-tests.xml");
- tobagoConfig.initDefaultValidatorInfo();
+ final TobagoConfig tobagoConfig = new TobagoConfig(
+ (ServletContext) facesContext.getExternalContext().getContext(), "tobago-config-for-unit-tests.xml");
servletContext.setAttribute(TOBAGO_CONFIG, tobagoConfig);
facesContext.getExternalContext().getApplicationMap().put(TOBAGO_CONFIG, tobagoConfig);
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/TobagoConfigMergingUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/TobagoConfigMergingUnitTest.java
index 5c7bf8e..b4c1c94 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/TobagoConfigMergingUnitTest.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/TobagoConfigMergingUnitTest.java
@@ -19,57 +19,45 @@
package org.apache.myfaces.tobago.internal.config;
+import org.apache.myfaces.tobago.config.TobagoConfig;
import org.apache.myfaces.tobago.context.Theme;
import org.apache.myfaces.tobago.context.ThemeScript;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
+
import java.util.Map;
public class TobagoConfigMergingUnitTest {
@Test
- public void testPreventFrameAttacksCascadingDefault()
- throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
+ public void testPreventFrameAttacksCascadingDefault() {
- final TobagoConfigImpl config = load(
- "tobago-config-merge-0.xml",
- "tobago-config-merge-1.xml");
+ final TobagoConfig config =
+ new TobagoConfig(null, "tobago-config-merge-0.xml", "tobago-config-merge-1.xml");
Assertions.assertFalse(config.isPreventFrameAttacks());
}
@Test
- public void testPreventFrameAttacks()
- throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
+ public void testPreventFrameAttacks() {
- final TobagoConfigImpl config = load("tobago-config-merge-0.xml");
+ final TobagoConfig config = new TobagoConfig(null, "tobago-config-merge-0.xml");
Assertions.assertFalse(config.isPreventFrameAttacks());
}
@Test
- public void testPreventFrameAttacksDefault()
- throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
+ public void testPreventFrameAttacksDefault() {
- final TobagoConfigImpl config = load("tobago-config-merge-1.xml");
+ final TobagoConfig config = new TobagoConfig(null, "tobago-config-merge-1.xml");
Assertions.assertTrue(config.isPreventFrameAttacks());
}
@Test
- public void testContentSecurityPolicy()
- throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
+ public void testContentSecurityPolicy() {
- final TobagoConfigImpl config = load(
- "tobago-config-merge-0.xml");
+ final TobagoConfig config = new TobagoConfig(null, "tobago-config-merge-0.xml");
Assertions.assertSame(config.getContentSecurityPolicy().getMode(), ContentSecurityPolicy.Mode.ON);
final Map<String, String> directiveMap = config.getContentSecurityPolicy().getDirectiveMap();
@@ -78,12 +66,10 @@ public class TobagoConfigMergingUnitTest {
}
@Test
- public void testContentSecurityPolicyExtend()
- throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
+ public void testContentSecurityPolicyExtend() {
- final TobagoConfigImpl config = load(
- "tobago-config-merge-0.xml",
- "tobago-config-merge-1.xml");
+ final TobagoConfig config =
+ new TobagoConfig(null, "tobago-config-merge-0.xml", "tobago-config-merge-1.xml");
Assertions.assertSame(config.getContentSecurityPolicy().getMode(), ContentSecurityPolicy.Mode.REPORT_ONLY);
final Map<String, String> directiveMap = config.getContentSecurityPolicy().getDirectiveMap();
@@ -93,12 +79,9 @@ public class TobagoConfigMergingUnitTest {
}
@Test
- public void testContentSecurityPolicyOff()
- throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
+ public void testContentSecurityPolicyOff() {
- final TobagoConfigImpl config = load(
- "tobago-config-merge-0.xml",
- "tobago-config-merge-1.xml",
+ final TobagoConfig config = new TobagoConfig(null, "tobago-config-merge-0.xml", "tobago-config-merge-1.xml",
"tobago-config-merge-2.xml");
Assertions.assertSame(config.getContentSecurityPolicy().getMode(), ContentSecurityPolicy.Mode.OFF);
@@ -106,12 +89,10 @@ public class TobagoConfigMergingUnitTest {
}
@Test
- public void testContentSecurityPolicyNameAttribute()
- throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
+ public void testContentSecurityPolicyNameAttribute() {
- final TobagoConfigImpl config = load(
- "tobago-config-merge-0.xml",
- "tobago-config-merge-3.xml");
+ final TobagoConfig config =
+ new TobagoConfig(null, "tobago-config-merge-0.xml", "tobago-config-merge-3.xml");
Assertions.assertSame(config.getContentSecurityPolicy().getMode(), ContentSecurityPolicy.Mode.ON);
final Map<String, String> directiveMap = config.getContentSecurityPolicy().getDirectiveMap();
@@ -120,12 +101,9 @@ public class TobagoConfigMergingUnitTest {
}
@Test
- public void testMimeTypes()
- throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
+ public void testMimeTypes() {
- final TobagoConfigImpl config = load(
- "tobago-config-merge-0.xml",
- "tobago-config-merge-1.xml",
+ final TobagoConfig config = new TobagoConfig(null, "tobago-config-merge-0.xml", "tobago-config-merge-1.xml",
"tobago-config-merge-2.xml");
final Map<String, String> mimeTypes = config.getMimeTypes();
@@ -136,11 +114,10 @@ public class TobagoConfigMergingUnitTest {
}
@Test
- public void testResourcePriority()
- throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
+ public void testResourcePriority() {
- final TobagoConfigImpl config = load(
- "tobago-config-5.0.xml", "tobago-config-5.0-replace.xml");
+ final TobagoConfig config =
+ new TobagoConfig(null, "tobago-config-5.0.xml", "tobago-config-5.0-replace.xml");
final String[] expected = new String[]{
"script-1.js",
@@ -171,12 +148,10 @@ public class TobagoConfigMergingUnitTest {
}
@Test
- public void testMergeThemePatch()
- throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
+ public void testMergeThemePatch() {
- final TobagoConfigImpl config12 = load(
- "tobago-config-theme-merge-1.xml",
- "tobago-config-theme-merge-2.xml");
+ final TobagoConfig config12 =
+ new TobagoConfig(null, "tobago-config-theme-merge-1.xml", "tobago-config-theme-merge-2.xml");
Assertions.assertEquals("2.0", config12.getDefaultTheme().getVersion());
final ThemeScript[] scripts12 = config12.getDefaultTheme().getScriptResources(false);
@@ -184,9 +159,8 @@ public class TobagoConfigMergingUnitTest {
Assertions.assertEquals("script-1", scripts12[0].getName());
Assertions.assertEquals("script-2", scripts12[1].getName());
- final TobagoConfigImpl config21 = load(
- "tobago-config-theme-merge-2.xml",
- "tobago-config-theme-merge-1.xml");
+ final TobagoConfig config21 =
+ new TobagoConfig(null, "tobago-config-theme-merge-2.xml", "tobago-config-theme-merge-1.xml");
Assertions.assertEquals("2.0", config21.getDefaultTheme().getVersion());
final ThemeScript[] scripts21 = config21.getDefaultTheme().getScriptResources(false);
@@ -195,22 +169,4 @@ public class TobagoConfigMergingUnitTest {
Assertions.assertEquals("script-2", scripts21[1].getName());
}
- public static TobagoConfigImpl load(final String... names)
- throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
-
- final List<TobagoConfigFragment> list = new ArrayList<>();
-
- for (final String name : names) {
- final URL url = TobagoConfigMergingUnitTest.class.getClassLoader().getResource(name);
- final TobagoConfigParser parser = new TobagoConfigParser();
- list.add(parser.parse(url));
- }
-
- final TobagoConfigSorter sorter = new TobagoConfigSorter(list);
- final TobagoConfigMerger merger = new TobagoConfigMerger(sorter.topologicalSort());
- final TobagoConfigImpl result = merger.merge();
- result.resolveThemes();
- result.lock();
- return result;
- }
}
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/TobagoConfigSorterUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/TobagoConfigSorterUnitTest.java
index d71964a..b793db8 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/TobagoConfigSorterUnitTest.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/TobagoConfigSorterUnitTest.java
@@ -99,20 +99,19 @@ public class TobagoConfigSorterUnitTest {
list.add(m);
list.add(n);
- final TobagoConfigSorter sorter = new TobagoConfigSorter(list);
- final List<TobagoConfigFragment> result = sorter.topologicalSort();
-
- Assertions.assertEquals(a, result.get(0));
- Assertions.assertEquals(b, result.get(1));
- Assertions.assertEquals(c, result.get(2));
- Assertions.assertEquals(u1, result.get(3));
- Assertions.assertEquals(u2, result.get(4));
- Assertions.assertEquals(d, result.get(5));
- Assertions.assertEquals(e, result.get(6));
- Assertions.assertEquals(f, result.get(7));
- Assertions.assertEquals(u3, result.get(8));
- Assertions.assertEquals(m, result.get(9));
- Assertions.assertEquals(n, result.get(10));
+ TobagoConfigSorter.sort(list);
+
+ Assertions.assertEquals(a, list.get(0));
+ Assertions.assertEquals(b, list.get(1));
+ Assertions.assertEquals(c, list.get(2));
+ Assertions.assertEquals(u1, list.get(3));
+ Assertions.assertEquals(u2, list.get(4));
+ Assertions.assertEquals(d, list.get(5));
+ Assertions.assertEquals(e, list.get(6));
+ Assertions.assertEquals(f, list.get(7));
+ Assertions.assertEquals(u3, list.get(8));
+ Assertions.assertEquals(m, list.get(9));
+ Assertions.assertEquals(n, list.get(10));
}
@Test
@@ -122,11 +121,9 @@ public class TobagoConfigSorterUnitTest {
final List<TobagoConfigFragment> list = new ArrayList<>();
- final TobagoConfigSorter sorter = new TobagoConfigSorter(list);
+ TobagoConfigSorter.sort(list);
- final List<TobagoConfigFragment> result = sorter.topologicalSort();
-
- Assertions.assertTrue(result.isEmpty());
+ Assertions.assertTrue(list.isEmpty());
}
@Test
@@ -142,10 +139,8 @@ public class TobagoConfigSorterUnitTest {
final List<TobagoConfigFragment> list = new ArrayList<>();
list.add(a);
- final TobagoConfigSorter sorter = new TobagoConfigSorter(list);
-
try {
- sorter.topologicalSort();
+ TobagoConfigSorter.sort(list);
Assertions.fail("Cycle was not detected!");
} catch (final RuntimeException e) {
@@ -166,10 +161,8 @@ public class TobagoConfigSorterUnitTest {
final List<TobagoConfigFragment> list = new ArrayList<>();
list.add(a);
- final TobagoConfigSorter sorter = new TobagoConfigSorter(list);
-
try {
- sorter.topologicalSort();
+ TobagoConfigSorter.sort(list);
Assertions.fail("Cycle was not detected!");
} catch (final RuntimeException e) {
@@ -196,10 +189,8 @@ public class TobagoConfigSorterUnitTest {
list.add(a);
list.add(b);
- final TobagoConfigSorter sorter = new TobagoConfigSorter(list);
-
try {
- sorter.topologicalSort();
+ TobagoConfigSorter.sort(list);
Assertions.fail("Cycle was not detected!");
} catch (final RuntimeException e) {
@@ -227,9 +218,8 @@ public class TobagoConfigSorterUnitTest {
list.add(a);
list.add(b);
- final TobagoConfigSorter sorter = new TobagoConfigSorter(list);
try {
- sorter.topologicalSort();
+ TobagoConfigSorter.sort(list);
Assertions.fail("Cycle was not detected!");
} catch (final RuntimeException e) {
@@ -261,10 +251,8 @@ public class TobagoConfigSorterUnitTest {
list.add(b);
list.add(c);
- final TobagoConfigSorter sorter = new TobagoConfigSorter(list);
-
try {
- sorter.topologicalSort();
+ TobagoConfigSorter.sort(list);
Assertions.fail("Cycle was not detected!");
} catch (final RuntimeException e) {
@@ -320,15 +308,13 @@ public class TobagoConfigSorterUnitTest {
list.add(standard);
list.add(core);
- final TobagoConfigSorter sorter = new TobagoConfigSorter(list);
-
- final List<TobagoConfigFragment> result = sorter.topologicalSort();
+ TobagoConfigSorter.sort(list);
- Assertions.assertEquals(core, result.get(0));
- Assertions.assertEquals(standard, result.get(1));
- Assertions.assertEquals(blank, result.get(6));
- final int blankPos = result.indexOf(blank);
- final int speysidePos = result.indexOf(speyside);
+ Assertions.assertEquals(core, list.get(0));
+ Assertions.assertEquals(standard, list.get(1));
+ Assertions.assertEquals(blank, list.get(6));
+ final int blankPos = list.indexOf(blank);
+ final int speysidePos = list.indexOf(speyside);
Assertions.assertTrue(blankPos > speysidePos);
}
}