From 127ff16e5923e244dcf30d775e6f1fd8f1825070 Mon Sep 17 00:00:00 2001 From: jensp Date: Tue, 19 Jan 2016 19:08:51 +0000 Subject: [PATCH] CCM NG: TemplatingConfig migrated to new configuration system, WebConfig almost migrated git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3807 8810af33-2d31-482b-a856-94f89814c4df --- .../com/arsdigita/mail/LegacyMailConfig.java | 157 ------ .../templating/PatternStylesheetResolver.java | 226 ++++---- .../com/arsdigita/templating/Templating.java | 88 +-- .../templating/TemplatingConfig.java | 235 ++++---- .../com/arsdigita/web/LegacyWebConfig.java | 319 +++++++++++ .../src/main/java/com/arsdigita/web/URL.java | 16 +- .../src/main/java/com/arsdigita/web/Web.java | 6 +- .../java/com/arsdigita/web/WebConfig.java | 502 ++++++++---------- .../workflow/simple/WorkflowConfig.java | 135 ++--- .../TemplatingConfigDescription.properties | 31 ++ .../TemplatingConfig_parameter.properties | 16 - .../WorkflowConfigDescription.properties | 25 + .../WorkflowConfig_parameter.properties | 8 - .../java/com/arsdigita/web/WebConfigTest.java | 200 +++++++ 14 files changed, 1192 insertions(+), 772 deletions(-) delete mode 100755 ccm-core/src/main/java/com/arsdigita/mail/LegacyMailConfig.java create mode 100644 ccm-core/src/main/java/com/arsdigita/web/LegacyWebConfig.java create mode 100644 ccm-core/src/main/resources/com/arsdigita/templating/TemplatingConfigDescription.properties delete mode 100755 ccm-core/src/main/resources/com/arsdigita/templating/TemplatingConfig_parameter.properties create mode 100644 ccm-core/src/main/resources/com/arsdigita/workflow/simple/WorkflowConfigDescription.properties delete mode 100755 ccm-core/src/main/resources/com/arsdigita/workflow/simple/WorkflowConfig_parameter.properties create mode 100644 ccm-core/src/test/java/com/arsdigita/web/WebConfigTest.java diff --git a/ccm-core/src/main/java/com/arsdigita/mail/LegacyMailConfig.java b/ccm-core/src/main/java/com/arsdigita/mail/LegacyMailConfig.java deleted file mode 100755 index 3b68a910f..000000000 --- a/ccm-core/src/main/java/com/arsdigita/mail/LegacyMailConfig.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. - * - * This library 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 library 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 library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -package com.arsdigita.mail; - -import com.arsdigita.runtime.AbstractConfig; -import com.arsdigita.util.parameter.BooleanParameter; -import com.arsdigita.util.parameter.ErrorList; -import com.arsdigita.util.parameter.Parameter; -import com.arsdigita.util.parameter.ParameterError; -import com.arsdigita.util.parameter.StringParameter; -import com.arsdigita.util.parameter.URLParameter; -import com.arsdigita.util.UncheckedWrapperException; - -import java.io.IOException; -import java.net.URL; -import java.util.Properties; - -/** - * LegacyMailConfig - * - * @author Rafael H. Schloming <rhs@mit.edu> - * @version $Revision: #7 $ $Date: 2004/08/16 $ - * @version $Id: LegacyMailConfig.java 1513 2007-03-22 09:09:03Z chrisgilbert23 $ - */ -public final class LegacyMailConfig extends AbstractConfig { - - private Properties m_props; - - private final Parameter m_debug = new BooleanParameter - ("waf.mail.debug", Parameter.OPTIONAL, Boolean.FALSE); - - private final Parameter m_javamail = new PropertyFileParameter - ("waf.mail.javamail.configuration", Parameter.OPTIONAL, null); - - /* used by Mail when the user is not logged in. */ - private final Parameter m_defaultFrom = new StringParameter - ("waf.mail.default_from", Parameter.OPTIONAL, ""); - - private final Parameter m_sendHTML = new BooleanParameter - ("waf.mail.send_html_mail", Parameter.OPTIONAL, Boolean.FALSE); - - - /** - * Constructor registers the parameter ands loads values from config file. - * - */ - public LegacyMailConfig() { - register(m_javamail); - register(m_debug); - register(m_defaultFrom); - register(m_sendHTML); - - loadInfo(); - } - - public Properties getJavamail() { - if (m_props == null) { - URL propsFile = (URL) get(m_javamail); - if (propsFile == null) { - m_props = new Properties(); - m_props.put("mail.transport.protocol", "smtp"); - m_props.put("mail.smtp.host", "localhost"); - } else { - try { - m_props = PropertyFileParameter.getProperties(propsFile); - } catch (IOException ioe) { - throw new UncheckedWrapperException - ("unable to retrieve properties file from " - + propsFile, ioe); - } - } - } - - return m_props; - } - - /** - * - * @return - */ - public String getDefaultFrom() { - String from = (String) get(m_defaultFrom); -//TODO: usage of arsdigita.web.Web, not sure if the class will be kept in ccm_ng - -// if (null == from) -// from = "notloggedin@" + Web.getConfig().getServer().getName(); - - return from; - } - - /** - * - * @return - */ - public boolean isDebug() { - return get(m_debug).equals(Boolean.TRUE); - } - - /** - * determine whether messages with mime type text/html - * should be sent as html emails (with plain text alternative) or - * just sent as translated plain text - * @return - */ - public boolean sendHTMLMessageAsHTMLEmail () { - return ((Boolean)get(m_sendHTML)).booleanValue(); - } - - - - /** - * - */ - private static class PropertyFileParameter extends URLParameter { - PropertyFileParameter(String name, int multiplicity, Object defaalt) { - super(name, multiplicity, defaalt); - } - - @Override - protected void doValidate(Object value, ErrorList errors) { - super.doValidate(value, errors); - - if (!errors.isEmpty()) { - return; - } - - try { - getProperties((URL) value); - } catch (IOException ioe) { - errors.add(new ParameterError(this, ioe)); - } - } - - public static Properties getProperties(URL url) throws IOException { - Properties props = new Properties(); - props.load(url.openStream()); - return props; - } - } - -} diff --git a/ccm-core/src/main/java/com/arsdigita/templating/PatternStylesheetResolver.java b/ccm-core/src/main/java/com/arsdigita/templating/PatternStylesheetResolver.java index 6c69f93d3..5885bc307 100755 --- a/ccm-core/src/main/java/com/arsdigita/templating/PatternStylesheetResolver.java +++ b/ccm-core/src/main/java/com/arsdigita/templating/PatternStylesheetResolver.java @@ -43,15 +43,15 @@ import org.apache.log4j.Logger; /** *

* This stylesheet resolver is used by the *PresentationManager - * class to work out which XSLT stylesheet to apply to the current Bebop - * XML output. + * class to work out which XSLT stylesheet to apply to the current Bebop XML + * output. *

* *

- * This particular stylesheet resolver uses a flat file containing a list - * of stylesheet patterns, one per line. The file is called - * WEB-INF/resources/stylesheet-paths.txt. - * Such a file could look like this: + * This particular stylesheet resolver uses a flat file containing a list of + * stylesheet patterns, one per line. The file is called + * WEB-INF/resources/stylesheet-paths.txt. Such a file could look + * like this: *

* *
@@ -71,57 +71,57 @@ import org.apache.log4j.Logger;
  * 

* *

- * The patterns, such as ::vhost::, are substituted - * for string values: + * The patterns, such as ::vhost::, are substituted for string + * values: *

* * * * - * - * - * + * + * + * * * - * - * - * + * + * + * * * - * - * - * + * + * + * * * - * - * - * + * + * + * * * - * - * - * + * + * + * * * - * - * - * + * + * + * * * - * - * - * + * + * + * * * - * - * - * + * + * + * * - * clear - * - * - * - * + * clear + * + * + * + * * *
Pattern Meaning Examples
::host:: Host name www.aplaws.org ::host:: Host name www.aplaws.org
::vhost:: Virtual hostname. business.camden.gov.uk ::vhost:: Virtual hostname. business.camden.gov.uk
::webapp:: Current web application name (ie. context or document root) ccm ::webapp:: Current web application name (ie. context or document root) ccm
::application:: Current CCM Application name navigation ::application:: Current CCM Application name navigation
::url:: URL stub of the current applications name tree admin ::url:: URL stub of the current applications name tree admin
::prefix:: ?? ?? ::prefix:: ?? ??
::outputtype:: Output format. text_html ::outputtype:: Output format. text_html
::locale:: Current locale fr_FR ::locale:: Current locale fr_FR
::outputtype:: Output format. text_html
::outputtype:: Output format. text_html
* @@ -140,38 +140,38 @@ import org.apache.log4j.Logger; * The resolver looks at each stylesheet in turn, and the first one which * actually exists on disk is returned. *

- * - * Developer may customize the process by writing a custom pattern generator - * and add it in a custom integration package Initializer (e.g. ccm-ldn-aplaws) - * by following code: - * // Register additional PatternStyleSheetResolver for Web app. - * PatternStylesheetResolver.registerPatternGenerator( - * "[myKey]", - * new [My]PatternGenerator() - * ); - * + * + * Developer may customize the process by writing a custom pattern generator and + * add it in a custom integration package Initializer (e.g. ccm-ldn-aplaws) by + * following code: // Register additional PatternStyleSheetResolver for Web app. + * PatternStylesheetResolver.registerPatternGenerator( "[myKey]", new + * [My]PatternGenerator() ); + * * * @author Richard W.M. Jones */ public class PatternStylesheetResolver implements StylesheetResolver { - /** Internal logger instance to faciliate debugging. Enable logging output - * by editing /WEB-INF/conf/log4j.properties int the runtime environment - * and set com.arsdigita.templating.PatternStylesheetResolver=DEBUG - * by uncommenting or adding the line. */ - private static final Logger s_log = Logger.getLogger - (PatternStylesheetResolver.class); + /** + * Internal logger instance to faciliate debugging. Enable logging output by + * editing /WEB-INF/conf/log4j.properties int the runtime environment and + * set com.arsdigita.templating.PatternStylesheetResolver=DEBUG by + * uncommenting or adding the line. + */ + private static final Logger s_log = Logger.getLogger( + PatternStylesheetResolver.class); - /** List of registered pattern generators which are queried in turn. */ + /** + * List of registered pattern generators which are queried in turn. + */ private static final HashMap s_generators = new HashMap(); - /** * Registers a new pattern generator for the given key. * * @param key the key as it appears in the pattern string - * @param gen a pattern generator for producing values to be - * substituted for key + * @param gen a pattern generator for producing values to be substituted for + * key */ public static void registerPatternGenerator(String key, PatternGenerator gen) { @@ -182,39 +182,38 @@ public class PatternStylesheetResolver implements StylesheetResolver { * at load time. */ static { s_log.debug("Static initalizer starting..."); - registerPatternGenerator - ("locale", new LocalePatternGenerator()); - registerPatternGenerator - ("url", new URLPatternGenerator()); - registerPatternGenerator - ("application", new ApplicationPatternGenerator()); - registerPatternGenerator - ("outputtype", new OutputTypePatternGenerator()); - registerPatternGenerator - ("prefix", new PrefixPatternGenerator()); - registerPatternGenerator - ("webapp", new WebAppPatternGenerator()); - registerPatternGenerator - ("host", new HostPatternGenerator()); + registerPatternGenerator("locale", new LocalePatternGenerator()); + registerPatternGenerator("url", new URLPatternGenerator()); + registerPatternGenerator("application", + new ApplicationPatternGenerator()); + registerPatternGenerator("outputtype", new OutputTypePatternGenerator()); + registerPatternGenerator("prefix", new PrefixPatternGenerator()); + registerPatternGenerator("webapp", new WebAppPatternGenerator()); + registerPatternGenerator("host", new HostPatternGenerator()); s_log.debug("Static initalizer finished."); } - /** Complete path to the file specifing stylesheet patterns. Configurable - * by configuration option in TemplatingConfig */ + /** + * Complete path to the file specifying stylesheet patterns. Configurable by + * configuration option in TemplatingConfig + */ private String m_path = null; - /** A List of Lists each of its lists containing one pattern to resolve - * a probably appropriate stylesheet to apply. (i.e. one row of the - * file m_path above) */ + /** + * A List of Lists each of its lists containing one pattern to resolve a + * probably appropriate stylesheet to apply. (i.e. one row of the file + * m_path above) + */ private List m_paths = null; /** - * + * * @param request - * @return + * + * @return */ @Override public URL resolve(HttpServletRequest request) { - synchronized(this) { + synchronized (this) { if (m_paths == null) { loadPaths(Templating.getConfig().getStylesheetPaths()); } @@ -226,7 +225,7 @@ public class PatternStylesheetResolver implements StylesheetResolver { Iterator it = m_paths.iterator(); while (it.hasNext()) { List pathList = (List) it.next(); - String[] bits = (String[])pathList.toArray( + String[] bits = (String[]) pathList.toArray( new String[pathList.size()] ); expandPlaceholders(bits, paths, values, request); @@ -234,7 +233,7 @@ public class PatternStylesheetResolver implements StylesheetResolver { Iterator files = paths.iterator(); while (files.hasNext()) { - String[] bits = (String[])files.next(); + String[] bits = (String[]) files.next(); String resource = StringUtils.join(bits, ""); // UGLY HACK @@ -242,10 +241,10 @@ public class PatternStylesheetResolver implements StylesheetResolver { // the root webapp) the provided string contains a "//" as there is // a slash before as well as after the placeholder in the pattern // string. It's ugly so we'll replace it. - resource = resource.replace("//","/"); + resource = resource.replace("//", "/"); // The hack destroys the http protocol as well so we need another hack - resource = resource.replace("http:/","http://"); - + resource = resource.replace("http:/", "http://"); + if (s_log.isInfoEnabled()) { s_log.info("Looking to see if resource " + resource + " exists"); } @@ -259,11 +258,11 @@ public class PatternStylesheetResolver implements StylesheetResolver { } if (s_log.isInfoEnabled()) { - s_log.info("origURL is " + origURL); + s_log.info("origURL is " + origURL); } - - final URL xfrmedURL = (origURL==null) ? null : Templating - .transformURL(origURL); + + final URL xfrmedURL = (origURL == null) ? null : Templating + .transformURL(origURL); if (s_log.isInfoEnabled()) { s_log.info("Transformed resource is " + xfrmedURL); @@ -288,21 +287,21 @@ public class PatternStylesheetResolver implements StylesheetResolver { } // fall through & try next pattern } catch (IOException ex) { - throw new UncheckedWrapperException("cannot open stream " + - resource, ex); + throw new UncheckedWrapperException("cannot open stream " + + resource, ex); } } - throw new RuntimeException("no path to XSL stylesheet found; " + - "try modifying " + m_path); + throw new RuntimeException("no path to XSL stylesheet found; " + + "try modifying " + m_path); } /** - * + * * @param inBits * @param paths * @param values - * @param request + * @param request */ private void expandPlaceholders(String[] inBits, ArrayList paths, @@ -310,31 +309,31 @@ public class PatternStylesheetResolver implements StylesheetResolver { HttpServletRequest request) { LinkedList queue = new LinkedList(); if (s_log.isDebugEnabled()) { - s_log.debug("Queue initial entry " + StringUtils.join(inBits, "")); + s_log.debug("Queue initial entry " + StringUtils.join(inBits, "")); } queue.add(inBits); while (!queue.isEmpty()) { - String[] bits = (String[])queue.removeFirst(); + String[] bits = (String[]) queue.removeFirst(); if (s_log.isDebugEnabled()) { s_log.debug("Process queue entry " + StringUtils.join(bits, "")); } boolean clean = true; - for (int i = 0 ; i < bits.length && clean ; i++) { + for (int i = 0; i < bits.length && clean; i++) { if (bits[i].startsWith("::") && bits[i].endsWith("::")) { clean = false; String[] vals = getValues(bits[i] - .substring(2, bits[i].length()-2), + .substring(2, bits[i].length() - 2), values, request); if (vals != null) { - for (int k = 0 ; k < vals.length ; k++) { + for (int k = 0; k < vals.length; k++) { String[] newBits = new String[bits.length]; // In case the pattern for an element is an empty // string (e.g. for the ROOT webapp) the slash before // as well as after the placeholder are added // resulting in a "//" which does no harm but is // ugly. - for (int j = 0 ; j < bits.length ; j++) { + for (int j = 0; j < bits.length; j++) { if (j == i) { newBits[j] = vals[k]; } else { @@ -342,8 +341,8 @@ public class PatternStylesheetResolver implements StylesheetResolver { } } if (s_log.isDebugEnabled()) { - s_log.debug("Requeue " + - StringUtils.join(newBits, "")); + s_log.debug("Requeue " + StringUtils.join( + newBits, "")); } queue.add(newBits); } @@ -353,8 +352,8 @@ public class PatternStylesheetResolver implements StylesheetResolver { if (clean) { if (s_log.isDebugEnabled()) { - s_log.debug("Finished expanding placeholders in " + - StringUtils.join(bits, "")); + s_log.debug("Finished expanding placeholders in " + + StringUtils.join(bits, "")); } paths.add(bits); } @@ -362,11 +361,12 @@ public class PatternStylesheetResolver implements StylesheetResolver { } /** - * + * * @param key * @param values * @param request - * @return + * + * @return */ private String[] getValues(String key, HashMap values, @@ -374,11 +374,11 @@ public class PatternStylesheetResolver implements StylesheetResolver { if (s_log.isDebugEnabled()) { s_log.debug("Lookup placeholder keys for " + key); } - String[] vals = (String[])values.get(key); + String[] vals = (String[]) values.get(key); if (vals == null) { PatternGenerator gen = (PatternGenerator) s_generators.get(key); if (gen == null) { - return new String[] {}; + return new String[]{}; } vals = gen.generateValues(key, request); values.put(key, vals); @@ -387,8 +387,8 @@ public class PatternStylesheetResolver implements StylesheetResolver { } /** - * - * @param path + * + * @param path */ private void loadPaths(String path) { if (s_log.isInfoEnabled()) { @@ -404,8 +404,8 @@ public class PatternStylesheetResolver implements StylesheetResolver { s_log.debug("stream.available is " + stream.available()); m_paths = new ArrayList(); - LineNumberReader file = new LineNumberReader - (new InputStreamReader(stream)); + LineNumberReader file = new LineNumberReader(new InputStreamReader( + stream)); String line; int lineNum; while ((line = file.readLine()) != null) { @@ -428,7 +428,7 @@ public class PatternStylesheetResolver implements StylesheetResolver { "cannot read XSLT paths from " + path, ex); } catch (Exception e) { - s_log.debug("loadPaths threw exception " + e); + s_log.debug("loadPaths threw exception " + e); } } diff --git a/ccm-core/src/main/java/com/arsdigita/templating/Templating.java b/ccm-core/src/main/java/com/arsdigita/templating/Templating.java index 3e2d3389d..ca5473502 100755 --- a/ccm-core/src/main/java/com/arsdigita/templating/Templating.java +++ b/ccm-core/src/main/java/com/arsdigita/templating/Templating.java @@ -77,38 +77,39 @@ public class Templating { * Config object containing various parameter */ private static final TemplatingConfig s_config = TemplatingConfig - .getInstanceOf(); + .getConfig(); static { s_log.debug("Static initalizer starting..."); Exceptions.registerUnwrapper( - TransformerException.class, - new ExceptionUnwrapper() { + TransformerException.class, + new ExceptionUnwrapper() { @Override public Throwable unwrap(Throwable t) { TransformerException ex = (TransformerException) t; return ex.getCause(); } + }); // now we initiate the CacheTable here // default cache size used to be 50, which is too high I reckon, // each template can eat up to 4 megs - Integer setting = s_config.getCacheSize(); + Integer setting = s_config.getStylesheetCacheSize(); int cacheSize = (setting == null ? 10 : setting.intValue()); - setting = s_config.getCacheAge(); + setting = s_config.getStylesheetCacheAge(); int cacheAge = (setting == null ? 60 * 60 * 24 * 3 : setting.intValue()); s_log.debug("Static initalizer finished..."); } /** - * Gets the TemplatingConfig record. + * Gets the LegacyTemplatingConfig record. * - * @return The TemplatingConfig of this runtime + * @return The LegacyTemplatingConfig of this runtime */ public static TemplatingConfig getConfig() { return s_config; @@ -139,7 +140,7 @@ public class Templating { public static PresentationManager getPresentationManager() { try { return (PresentationManager) BebopConfig.getConfig(). - getPresenterClass().newInstance(); + getPresenterClass().newInstance(); } catch (IllegalAccessException | InstantiationException ex) { throw new UncheckedWrapperException(ex); } @@ -151,8 +152,9 @@ public class Templating { * was first generated, it will be regenerated first. * * @param source the URL to the top-level template resource + * * @return an XSLTemplate instance representing - * source + * source */ public static synchronized XSLTemplate getTemplate(final URL source) { return getTemplate(source, false, true); @@ -163,15 +165,18 @@ public class Templating { * cache, it will be returned. If the template has been modified since it * was first generated, it will be regenerated first. * - * @param source the URL to the top-level template resource + * @param source the URL to the top-level template + * resource * @param fancyErrors Should this place any xsl errors in the request for - * use by another class. If this is true, the the errors are stored for - * later use. - * @param useCache Should the templates be pulled from cache, if available? - * True means they are pulled from cache. False means they are pulled from - * the disk. If this is false the pages are also not placed in the cache. + * use by another class. If this is true, the the errors + * are stored for later use. + * @param useCache Should the templates be pulled from cache, if + * available? True means they are pulled from cache. + * False means they are pulled from the disk. If this is + * false the pages are also not placed in the cache. + * * @return an XSLTemplate instance representing - * source + * source */ public static synchronized XSLTemplate getTemplate(final URL source, boolean fancyErrors, @@ -188,7 +193,7 @@ public class Templating { if (template == null) { if (s_log.isInfoEnabled()) { s_log.info("The template for URL " + source + " is not " - + "cached; creating and caching it now"); + + "cached; creating and caching it now"); } if (fancyErrors) { @@ -201,14 +206,14 @@ public class Templating { } } else if (KernelConfig.getConfig().isDebugEnabled() - && template.isModified()) { + && template.isModified()) { // XXX referencing Kernel above is a broken dependency. // Debug mode should be captured at a lower level, // probably on UtilConfig. if (s_log.isInfoEnabled()) { s_log.info("Template " + template + " has been modified; " - + "recreating it from scratch"); + + "recreating it from scratch"); } if (fancyErrors) { @@ -228,6 +233,7 @@ public class Templating { * Resolves and retrieves the template for the given request. * * @param sreq The current request object + * * @return The resolved XSLTemplate instance */ public static XSLTemplate getTemplate(final HttpServletRequest sreq) { @@ -237,13 +243,15 @@ public class Templating { /** * Resolves the template for the given request to an URL. * - * @param sreq The current request object + * @param sreq The current request object * @param fancyErrors Should this place any xsl errors in the request for - * use by another class. If this is true, the the errors are stored for - * later use. - * @param useCache Should the templates be pulled from cache, if available? - * True means they are pulled from cache. False means they are pulled from - * the disk. If this is false the pages are also not placed in the cache. + * use by another class. If this is true, the the errors + * are stored for later use. + * @param useCache Should the templates be pulled from cache, if + * available? True means they are pulled from cache. + * False means they are pulled from the disk. If this is + * false the pages are also not placed in the cache. + * * @return The resolved XSLTemplate instance */ public static XSLTemplate getTemplate(final HttpServletRequest sreq, @@ -286,6 +294,7 @@ public class Templating { * Generates a stream containing imports for a number of URLs. * * @param paths An iterator of java.net.URL objects + * * @return a virtual XSL file */ public static InputStream multiplexXSLFiles(Iterator paths) { @@ -298,8 +307,8 @@ public class Templating { URL path = (URL) paths.next(); Element imp = root.newChildElement( - "xsl:import", - "http://www.w3.org/1999/XSL/Transform"); + "xsl:import", + "http://www.w3.org/1999/XSL/Transform"); imp.addAttribute("href", path.toString()); if (s_log.isInfoEnabled()) { @@ -352,8 +361,8 @@ public class Templating { // Check if the url refers to our own host if (self.getName().equals(url.getHost()) - && ((self.getPort() == url.getPort()) - || (url.getPort() == -1 && self.getPort() == 80))) { + && ((self.getPort() == url.getPort()) + || (url.getPort() == -1 && self.getPort() == 80))) { // host part denotes to a local resource, cut off host part. localPath = url.getPath(); isLocal = true; @@ -391,21 +400,21 @@ public class Templating { URL newURL = Web.findResource(localPath); //without host part here! if (s_log.isDebugEnabled()) { s_log. - debug("Transforming resource " + url + " to " - + newURL); + debug("Transforming resource " + url + " to " + + newURL); } return newURL; } else { // A real path to disk final String filename = Web.getServletContext() - .getRealPath(localPath); + .getRealPath(localPath); File file = new File(filename); if (file.exists()) { try { URL newURL = file.toURL(); if (s_log.isDebugEnabled()) { s_log.debug("Transforming resource " + url + " to " - + newURL); + + newURL); } return newURL; } catch (MalformedURLException ex) { @@ -413,17 +422,20 @@ public class Templating { } } else if (s_log.isDebugEnabled()) { s_log.debug("File " + filename - + " doesn't exist on disk"); + + " doesn't exist on disk"); } } } else // url is not the (local) running CCM host, no transformation // is done - if (s_log.isDebugEnabled()) { + { + if (s_log.isDebugEnabled()) { s_log.debug("URL " + url + " is not local"); } + } return url; // returns the original, unmodified url here } + } /** @@ -433,7 +445,8 @@ public class Templating { class LoggingErrorListener implements ErrorListener { private static final Logger s_log - = Logger.getLogger(LoggingErrorListener.class); + = Logger.getLogger( + LoggingErrorListener.class); private final ArrayList m_errors; LoggingErrorListener() { @@ -461,9 +474,10 @@ class LoggingErrorListener implements ErrorListener { private void log(Level level, TransformerException ex) { s_log.log(level, "Transformer " + level + ": " - + ex.getLocationAsString() + ": " + ex. + + ex.getLocationAsString() + ": " + ex. getMessage(), ex); m_errors.add(ex); } + } diff --git a/ccm-core/src/main/java/com/arsdigita/templating/TemplatingConfig.java b/ccm-core/src/main/java/com/arsdigita/templating/TemplatingConfig.java index 34f6ec702..df07074d5 100755 --- a/ccm-core/src/main/java/com/arsdigita/templating/TemplatingConfig.java +++ b/ccm-core/src/main/java/com/arsdigita/templating/TemplatingConfig.java @@ -1,122 +1,177 @@ /* - * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. + * Copyright (C) 2016 LibreCCM Foundation. * * This library 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. + * 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 library 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 + * 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 library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA */ package com.arsdigita.templating; -import com.arsdigita.runtime.AbstractConfig; -import com.arsdigita.util.parameter.Parameter; -import com.arsdigita.util.parameter.IntegerParameter; -import com.arsdigita.util.parameter.SingletonParameter; -import com.arsdigita.util.parameter.StringParameter; -import org.apache.log4j.Logger; +import com.arsdigita.util.UncheckedWrapperException; +import com.arsdigita.web.ApplicationFileResolver; + +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.configuration.Configuration; +import org.libreccm.configuration.ConfigurationManager; +import org.libreccm.configuration.Setting; + +import java.util.Objects; /** - * @author Justin Ross - * @version $Id$ + * + * @author Jens Pelzetter */ -public final class TemplatingConfig extends AbstractConfig { +@Configuration +public final class TemplatingConfig { - /** Internal logger instance to faciliate debugging. Enable logging output - * by editing /WEB-INF/conf/log4j.properties int hte runtime environment - * and set com.arsdigita.templating.TemplatingConfig=DEBUG by uncommenting - * it */ - private static final Logger s_log = Logger.getLogger - (TemplatingConfig.class); + @Setting + private String stylesheetPaths = "/WEB-INF/resources/stylesheet-paths.txt"; - /** Singelton config object. */ - private static TemplatingConfig s_conf; - /** - * Gain a WorkspaceConfig object. - * - * Singelton pattern, don't instantiate a config object using the - * constructor directly! - * @return - */ - public static synchronized TemplatingConfig getInstanceOf() { - if (s_conf == null) { - s_conf = new TemplatingConfig(); - s_conf.load(); + @Setting + private String stylesheetResolverClass = PatternStylesheetResolver.class + .getName(); + + @Setting + private Integer stylesheetCacheSize = 10; + + @Setting + private Integer stylesheetCacheAge = 3600; + + public static TemplatingConfig getConfig() { + final CdiUtil cdiUtil = new CdiUtil(); + final ConfigurationManager confManager = cdiUtil.findBean( + ConfigurationManager.class); + return confManager.findConfiguration(TemplatingConfig.class); + } + + public String getStylesheetPaths() { + return stylesheetPaths; + } + + public void setStylesheetPaths(final String stylesheetPaths) { + this.stylesheetPaths = stylesheetPaths; + } + + public String getStylesheetResolverClass() { + return stylesheetResolverClass; + } + + public StylesheetResolver getStylesheetResolver() { + + try { + @SuppressWarnings("unchecked") + final Class clazz + = (Class) Class + .forName(stylesheetResolverClass); + return clazz.newInstance(); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) { + throw new UncheckedWrapperException( + "Unable to create configured StylesheetResolver.", + ex); + } + } + + public void setStylesheetResolverClass( + final String stylesheetResolverClass) { + try { + final Class clazz = Class.forName(stylesheetResolverClass); + if (!StylesheetResolver.class.isAssignableFrom(clazz)) { + throw new IllegalArgumentException(String.format( + "Provided class \"%s\" is not an " + + "implementation of the interface \"%s\".", + stylesheetResolverClass, + StylesheetResolver.class.getName())); + } + } catch (ClassNotFoundException ex) { + throw new IllegalArgumentException( + String.format("Unable to retrieve class \"%s\".", + stylesheetResolverClass), + ex); } - return s_conf; + this.stylesheetResolverClass = stylesheetResolverClass; } - /** Fully qualified path string to file contain the pattern file for - {@link com.arsdigita.templating.PatternStylesheetResolver - PatternStylesheetResolver} */ - private final Parameter m_paths = new StringParameter - ("waf.templating.stylesheet_paths", Parameter.REQUIRED, - "/WEB-INF/resources/stylesheet-paths.txt"); - - /** Specifies class for the implementation of StylesheetResolver Interface - to resolve a modules stylesheet. */ - private final Parameter m_resolver = new SingletonParameter - ("waf.templating.stylesheet_resolver", Parameter.REQUIRED, - new PatternStylesheetResolver()); - - /** Specifies number of stylesheets cached. */ - private final Parameter m_cacheSize = new IntegerParameter - ("waf.templating.stylesheet_cache_size", Parameter.OPTIONAL, - null); - - /** Duration of stylesheet cache in seconds */ - private final Parameter m_cacheAge = new IntegerParameter - ("waf.templating.stylesheet_cache_age", Parameter.OPTIONAL, - null); - - public TemplatingConfig() { - - register(m_paths); - register(m_resolver); - register(m_cacheSize); - register(m_cacheAge); - - loadInfo(); + public Integer getStylesheetCacheSize() { + return stylesheetCacheSize; } - /** - * Get name and location of stylesheet pattern file. - * - * @return String with fully qualified file name - */ - final String getStylesheetPaths() { - return (String) get(m_paths); + public void setStylesheetCacheSize(final Integer stylesheetCacheSize) { + this.stylesheetCacheSize = stylesheetCacheSize; } - /** - * Gets the stylesheet resolver. This value is set via the - * com.arsdigita.templating.stylesheet_resolver - * system property. - * @return - */ - public final StylesheetResolver getStylesheetResolver() { - return (StylesheetResolver) get(m_resolver); + public Integer getStylesheetCacheAge() { + return stylesheetCacheAge; } - /** Can be null. - * @return */ - public final Integer getCacheSize() { - return (Integer) get(m_cacheSize); + public void setStylesheetCacheAge(final Integer stylesheetCacheAge) { + this.stylesheetCacheAge = stylesheetCacheAge; } - /** Can be null. - * @return */ - public final Integer getCacheAge() { - return (Integer) get(m_cacheAge); + @Override + public int hashCode() { + int hash = 7; + hash = 23 * hash + Objects.hashCode(stylesheetPaths); + hash = 23 * hash + Objects.hashCode(stylesheetResolverClass); + hash = 23 * hash + Objects.hashCode(stylesheetCacheSize); + hash = 23 * hash + Objects.hashCode(stylesheetCacheAge); + return hash; } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (obj instanceof TemplatingConfig) { + return false; + } + final TemplatingConfig other = (TemplatingConfig) obj; + if (!Objects.equals(stylesheetPaths, other.getStylesheetPaths())) { + return false; + } + if (!Objects.equals(stylesheetResolverClass, + other.getStylesheetResolverClass())) { + return false; + } + if (!Objects.equals(stylesheetCacheSize, + other.getStylesheetCacheSize())) { + return false; + } + if (!Objects.equals(stylesheetCacheAge, + other.getStylesheetCacheAge())) { + return false; + } + return true; + } + + @Override + public String toString() { + return String.format("%s{ " + + "stylesheetPaths = \"%s\", " + + "stylesheetResolverClass = \"%s\", " + + "stylesheetCacheSize = %d, " + + "stylesheetCacheAge = %d" + + " }", + super.toString(), + stylesheetPaths, + stylesheetResolverClass, + stylesheetCacheSize, + stylesheetCacheAge); + } + } diff --git a/ccm-core/src/main/java/com/arsdigita/web/LegacyWebConfig.java b/ccm-core/src/main/java/com/arsdigita/web/LegacyWebConfig.java new file mode 100644 index 000000000..40a48b876 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/web/LegacyWebConfig.java @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library 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 library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.web; + +import com.arsdigita.runtime.AbstractConfig; +import com.arsdigita.util.parameter.BooleanParameter; +import com.arsdigita.util.parameter.EnumerationParameter; +import com.arsdigita.util.parameter.ErrorList; +import com.arsdigita.util.parameter.Parameter; +import com.arsdigita.util.parameter.ParameterError; +import com.arsdigita.util.parameter.SingletonParameter; +import com.arsdigita.util.parameter.StringArrayParameter; +import com.arsdigita.util.parameter.StringParameter; +import com.arsdigita.util.servlet.HttpHost; +import com.arsdigita.util.servlet.HttpHostParameter; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * A record containing server-session scoped configuration properties. + * + * Accessors of this class may return null. Developers should take care to trap + * null return values in their code. + * + * @see com.arsdigita.web.Web + * @author Justin Ross <jross@redhat.com> + * @author Jens Pelzetter + */ +public class LegacyWebConfig extends AbstractConfig { + + private static final Logger LOGGER = LogManager.getLogger(LegacyWebConfig.class); + + private static LegacyWebConfig config; + + /** + * Returns the singleton configuration record for the content section + * environment. + * + * @return The CMSConfig record; it cannot be null + */ + public static synchronized LegacyWebConfig getInstanceOf() { + if (config == null) { + config = new LegacyWebConfig(); + config.load(); + } + return config; + } + + // ///////////////////////////////////////////////////////////////////////// + // Configuration parameter section + // ///////////////////////////////////////////////////////////////////////// + /** + * Determines what HTTP scheme prefix is used by default to generate URLs + * (either http od https) + */ + private final Parameter m_scheme = new DefaultSchemeParameter( + "waf.web.default_scheme", + Parameter.REQUIRED, "http"); + /** + * Sets the name and port that users of a site will see in URLs generated by + * CCM for the site. This is a required parameter during installation, e.g. + * example.com:80 + */ + private final Parameter m_server = new HttpHostParameter("waf.web.server"); + /** + * Name and port that users of a site will see in secure URLs generated by + * CCM for the site. As an example: example.com:443 + */ + private final Parameter m_secureServer = new HttpHostParameter( + "waf.web.secure_server", + Parameter.OPTIONAL, null); + /** + * The name of your website, for use in page footers for example. It's not + * necessarily the URL but rather a title, e.g. "House of HTML". If not + * specified set to the server's URL. + */ + private final Parameter m_site = new StringParameter("waf.web.site_name", + Parameter.OPTIONAL, + null) { + + @Override + public final Object getDefaultValue() { + final HttpHost host = getServer(); + if (host == null) { + return null; + } else { + return host.toString(); + } + } + + }; + /** + * Sets the name and port of the machine on which the CCM instance is + * running. Used to fetch some resources by a local URL avoiding external + * internet traffic (and delay). If not specified set to the servers's name + * redirecting all traffic to external internet address. + */ + private final Parameter m_host = new HttpHostParameter("waf.web.host", + Parameter.OPTIONAL, + null) { + + @Override + public final Object getDefaultValue() { + return getServer(); + } + + }; + + /** + * List of URLs which accessed by insecure (normal HTTP) connection produce + * a redirect to a HTTPS equivalent. List is comma separated. + */ + private final Parameter m_secureRequired = new StringArrayParameter( + "waf.web.secure_required", Parameter.OPTIONAL, null); + /** + * List of URLs which accessed by secure (HTTPS) connection produce a + * redirect to a HTTP equivalent. List is comma separated. + */ + private final Parameter m_secureSwitchBack = new StringArrayParameter( + "waf.web.secure_switchback", Parameter.OPTIONAL, null); + + /** + * Dispatcher servlet path. It's the prefix to the main entry point for any + * application request (CCMDispatcherServlet). By default /ccm + */ + private final Parameter m_servlet = new StringParameter( + "waf.web.dispatcher_servlet_path", Parameter.REQUIRED, "/ccm"); + + /** + * Specifies by name which implementation of ApplicationFileResolver is used + * to dynamically resolve static files. By default + * DefaultApplicationFileResolver() is used. + */ + private final Parameter m_resolver = new SingletonParameter( + "waf.web.application_file_resolver", + Parameter.OPTIONAL, + new DefaultApplicationFileResolver()); + + private final Parameter m_deactivate_cache_host_notifications + = new BooleanParameter( + "waf.web.deactivate_cache_host_notifications", + Parameter.OPTIONAL, Boolean.FALSE); + + private final Parameter m_dynamic_host_provider = new StringParameter( + "waf.web.dynamic_host_provider", + Parameter.OPTIONAL, ""); + + /** + * Constructor, but do NOT instantiate this class directly, use + * getInstanceOf() instead. (Singleton pattern!) + * + */ + public LegacyWebConfig() { + + register(m_scheme); + register(m_server); + register(m_secureServer); + register(m_site); + register(m_host); + register(m_secureRequired); + register(m_secureSwitchBack); + register(m_servlet); + register(m_resolver); + register(m_deactivate_cache_host_notifications); + register(m_dynamic_host_provider); + + loadInfo(); + } + + public final String getDefaultScheme() { + return (String) get(m_scheme); + } + + public final HttpHost getServer() { + return (HttpHost) get(m_server); + } + + public final HttpHost getSecureServer() { + return (HttpHost) get(m_secureServer); + } + + public final boolean isSecureRequired(String uri) { + String[] secured = (String[]) get(m_secureRequired); + if (secured != null) { + for (int i = 0, n = secured.length; i < n; i++) { + if (uri.startsWith(secured[i])) { + return true; + } + } + } + return false; + } + + public final boolean isNonSecureSwitchRequired(String uri) { + String[] switchBack = (String[]) get(m_secureSwitchBack); + if (switchBack != null) { + for (int i = 0, n = switchBack.length; i < n; i++) { + if (uri.startsWith(switchBack[i])) { + return true; + } + } + } + return false; + } + + public final String getDispatcherServletPath() { + return (String) get(m_servlet); + } + + public final ApplicationFileResolver getApplicationFileResolver() { + return (ApplicationFileResolver) get(m_resolver); + } + + public final HttpHost getHost() { + return (HttpHost) get(m_host); + } + + final void setHost(final HttpHost host) { + set(m_host, host); + } + + public final String getSiteName() { + return (String) get(m_site); + } + + /** + * + * @return + * @deprecated use Web.getContextPath() instead. The installation context + * must no longer manually configured + */ + // NO LONGER configured by configuration option but determined at runtime + // by CCMDispatcherServlet itself. + // // dispatcherContextPath option in old Initializer, set to "" + // m_context = new StringParameter + // ("waf.web.dispatcher_context_path", Parameter.REQUIRED, ""); + public final String getDispatcherContextPath() { + // return (String) get(m_context); + return CCMDispatcherServlet.getContextPath(); + } + + + private static class DispatcherServletPathParameter + extends StringParameter { + + DispatcherServletPathParameter(final String name) { + super(name); + } + + @Override + protected void doValidate(final Object value, final ErrorList errors) { + final String string = (String) value; + + if (string.endsWith("/")) { + final ParameterError error = new ParameterError(this, + "The value must not end in a '/'"); + errors.add(error); + } + } + + } + + private static class DefaultSchemeParameter extends EnumerationParameter { + + DefaultSchemeParameter(final String name, + final int multiplicity, + final Object defaalt) { + super(name, multiplicity, defaalt); + + put("http", "http"); + put("https", "https"); + } + + } + + protected DynamicHostProvider dhProvider = null; + protected boolean dhProviderInited = false; + + public final DynamicHostProvider getDynamicHostProvider() { + if (dhProviderInited == false) { + String classname = (String) get(m_dynamic_host_provider); + if (classname != null) { + try { + Class klass = Class.forName(classname); + dhProvider = (DynamicHostProvider) klass.newInstance(); + } catch (Exception e) { + LOGGER.error( + "Could not instantiate DynamicHostProvider using classname : " + + classname, e); + } + } + dhProviderInited = true; + } + return dhProvider; + } + + public final boolean getDeactivateCacheHostNotifications() { + return ((Boolean) get(m_deactivate_cache_host_notifications)) + .booleanValue(); + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/web/URL.java b/ccm-core/src/main/java/com/arsdigita/web/URL.java index 3410f268a..f982fdc66 100644 --- a/ccm-core/src/main/java/com/arsdigita/web/URL.java +++ b/ccm-core/src/main/java/com/arsdigita/web/URL.java @@ -120,7 +120,7 @@ import org.libreccm.web.CcmApplication; * *

* Those methods not taking an HttpServletRequest use the scheme, - * server name, and port defined in WebConfig.

+ * server name, and port defined in LegacyWebConfig.

* *

* All static create methods taking a ParameterMap take null to @@ -136,7 +136,7 @@ import org.libreccm.web.CcmApplication; * @see com.arsdigita.web.DispatcherServlet * @see com.arsdigita.web.LoginSignal * @see com.arsdigita.web.ReturnSignal - * @see com.arsdigita.web.WebConfig + * @see com.arsdigita.web.LegacyWebConfig * @see com.arsdigita.web.Application * @author Justin Ross * <jross@redhat.com> @@ -612,7 +612,7 @@ public class URL { * @return a URL to your server's root path */ public static final URL root() { - final WebConfig config = Web.getConfig(); + final LegacyWebConfig config = Web.getConfig(); URL url = new URL(config.getDefaultScheme(), config.getServer().getName(), @@ -679,7 +679,7 @@ public class URL { public static final URL there(final HttpServletRequest sreq, final String path, final ParameterMap params) { - final WebConfig config = Web.getConfig(); + final LegacyWebConfig config = Web.getConfig(); Assert.exists(sreq, "HttpServletRequest sreq"); Assert.exists(config, "WebConfig config"); @@ -715,7 +715,7 @@ public class URL { public static final URL dynamicHostThere(final HttpServletRequest sreq, final String path, final ParameterMap params) { - final WebConfig config = Web.getConfig(); + final LegacyWebConfig config = Web.getConfig(); DynamicHostProvider provider = Web.getConfig().getDynamicHostProvider(); if (provider == null) { @@ -755,7 +755,7 @@ public class URL { */ public static final URL there(final HttpServletRequest sreq, final String path) { - final WebConfig config = Web.getConfig(); + final LegacyWebConfig config = Web.getConfig(); Assert.exists(sreq, "HttpServletRequest sreq"); Assert.exists(config, "WebConfig config"); @@ -847,7 +847,7 @@ public class URL { */ public static final URL there(final String path, final ParameterMap params) { - final WebConfig config = Web.getConfig(); + final LegacyWebConfig config = Web.getConfig(); return new URL(config.getDefaultScheme(), config.getServer().getName(), @@ -949,7 +949,7 @@ public class URL { * @return */ public static String getDispatcherPath() { - final WebConfig config = Web.getConfig(); + final LegacyWebConfig config = Web.getConfig(); final HttpServletRequest req = Web.getRequest(); final String context = config.getDispatcherContextPath(); diff --git a/ccm-core/src/main/java/com/arsdigita/web/Web.java b/ccm-core/src/main/java/com/arsdigita/web/Web.java index b63d2565a..5055ebaf9 100644 --- a/ccm-core/src/main/java/com/arsdigita/web/Web.java +++ b/ccm-core/src/main/java/com/arsdigita/web/Web.java @@ -47,7 +47,7 @@ public class Web { */ private static final Logger s_log = Logger.getLogger(Web.class); - private static final WebConfig s_config = WebConfig.getInstanceOf(); + private static final LegacyWebConfig s_config = LegacyWebConfig.getInstanceOf(); private static final ThreadLocal s_request = new InternalRequestLocal(); private static final ThreadLocal s_servletContext @@ -90,9 +90,9 @@ public class Web { /** * Provide the configuration record for code in the web package. * - * @return A WebConfig configuration record; it cannot be null + * @return A LegacyWebConfig configuration record; it cannot be null */ - public static WebConfig getConfig() { + public static LegacyWebConfig getConfig() { return s_config; } diff --git a/ccm-core/src/main/java/com/arsdigita/web/WebConfig.java b/ccm-core/src/main/java/com/arsdigita/web/WebConfig.java index a845b3a5c..415bc453f 100644 --- a/ccm-core/src/main/java/com/arsdigita/web/WebConfig.java +++ b/ccm-core/src/main/java/com/arsdigita/web/WebConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 LibreCCM Foundation. + * Copyright (C) 2016 LibreCCM Foundation. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,302 +18,250 @@ */ package com.arsdigita.web; -import com.arsdigita.runtime.AbstractConfig; -import com.arsdigita.util.parameter.BooleanParameter; -import com.arsdigita.util.parameter.EnumerationParameter; -import com.arsdigita.util.parameter.ErrorList; -import com.arsdigita.util.parameter.Parameter; -import com.arsdigita.util.parameter.ParameterError; -import com.arsdigita.util.parameter.SingletonParameter; -import com.arsdigita.util.parameter.StringArrayParameter; -import com.arsdigita.util.parameter.StringParameter; -import com.arsdigita.util.servlet.HttpHost; -import com.arsdigita.util.servlet.HttpHostParameter; +import com.arsdigita.util.UncheckedWrapperException; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.configuration.Configuration; +import org.libreccm.configuration.ConfigurationManager; +import org.libreccm.configuration.Setting; + +import java.lang.reflect.Method; +import java.util.HashSet; +import java.util.Set; +import java.util.StringJoiner; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import javax.validation.constraints.Pattern; +import javax.validation.executable.ExecutableValidator; /** - * A record containing server-session scoped configuration properties. * - * Accessors of this class may return null. Developers should take care to trap - * null return values in their code. - * - * @see com.arsdigita.web.Web - * @author Justin Ross <jross@redhat.com> - * @author Jens Pelzetter + * @author Jens Pelzetter */ -public class WebConfig extends AbstractConfig { +@Configuration +public final class WebConfig { - private static final Logger LOGGER = LogManager.getLogger(WebConfig.class); + @Setting + private String defaultScheme = "http"; - private static WebConfig config; + @Setting + private String server; - /** - * Returns the singleton configuration record for the content section - * environment. - * - * @return The CMSConfig record; it cannot be null - */ - public static synchronized WebConfig getInstanceOf() { - if (config == null) { - config = new WebConfig(); - config.load(); - } - return config; + @Setting + private String secureServer; + + @Setting + private String siteName; + + @Setting + private String host; + + @Setting + private Set secureRequiredFor = new HashSet<>(); + + @Setting + private String dispatcherServletPath = "/ccm"; + + @Setting + private String resolverClass = DefaultApplicationFileResolver.class + .getName(); + + @Setting + private Boolean deactiveCacheHostNotifications = false; + + @Setting + private String dynamicHostProvider; + + public static WebConfig getConfig() { + final CdiUtil cdiUtil = new CdiUtil(); + final ConfigurationManager confManager = cdiUtil.findBean( + ConfigurationManager.class); + return confManager.findConfiguration(WebConfig.class); } - // ///////////////////////////////////////////////////////////////////////// - // Configuration parameter section - // ///////////////////////////////////////////////////////////////////////// - /** - * Determines what HTTP scheme prefix is used by default to generate URLs - * (either http od https) - */ - private final Parameter m_scheme = new DefaultSchemeParameter( - "waf.web.default_scheme", - Parameter.REQUIRED, "http"); - /** - * Sets the name and port that users of a site will see in URLs generated by - * CCM for the site. This is a required parameter during installation, e.g. - * example.com:80 - */ - private final Parameter m_server = new HttpHostParameter("waf.web.server"); - /** - * Name and port that users of a site will see in secure URLs generated by - * CCM for the site. As an example: example.com:443 - */ - private final Parameter m_secureServer = new HttpHostParameter( - "waf.web.secure_server", - Parameter.OPTIONAL, null); - /** - * The name of your website, for use in page footers for example. It's not - * necessarily the URL but rather a title, e.g. "House of HTML". If not - * specified set to the server's URL. - */ - private final Parameter m_site = new StringParameter("waf.web.site_name", - Parameter.OPTIONAL, - null) { + public String getDefaultScheme() { + return defaultScheme; + } - @Override - public final Object getDefaultValue() { - final HttpHost host = getServer(); - if (host == null) { - return null; - } else { - return host.toString(); - } - } - - }; - /** - * Sets the name and port of the machine on which the CCM instance is - * running. Used to fetch some resources by a local URL avoiding external - * internet traffic (and delay). If not specified set to the servers's name - * redirecting all traffic to external internet address. - */ - private final Parameter m_host = new HttpHostParameter("waf.web.host", - Parameter.OPTIONAL, - null) { - - @Override - public final Object getDefaultValue() { - return getServer(); - } - - }; - - /** - * List of URLs which accessed by insecure (normal HTTP) connection produce - * a redirect to a HTTPS equivalent. List is comma separated. - */ - private final Parameter m_secureRequired = new StringArrayParameter( - "waf.web.secure_required", Parameter.OPTIONAL, null); - /** - * List of URLs which accessed by secure (HTTPS) connection produce a - * redirect to a HTTP equivalent. List is comma separated. - */ - private final Parameter m_secureSwitchBack = new StringArrayParameter( - "waf.web.secure_switchback", Parameter.OPTIONAL, null); - - /** - * Dispatcher servlet path. It's the prefix to the main entry point for any - * application request (CCMDispatcherServlet). By default /ccm - */ - private final Parameter m_servlet = new StringParameter( - "waf.web.dispatcher_servlet_path", Parameter.REQUIRED, "/ccm"); - - /** - * Specifies by name which implementation of ApplicationFileResolver is used - * to dynamically resolve static files. By default - * DefaultApplicationFileResolver() is used. - */ - private final Parameter m_resolver = new SingletonParameter( - "waf.web.application_file_resolver", - Parameter.OPTIONAL, - new DefaultApplicationFileResolver()); - - private final Parameter m_deactivate_cache_host_notifications - = new BooleanParameter( - "waf.web.deactivate_cache_host_notifications", - Parameter.OPTIONAL, Boolean.FALSE); - - private final Parameter m_dynamic_host_provider = new StringParameter( - "waf.web.dynamic_host_provider", - Parameter.OPTIONAL, ""); - - /** - * Constructor, but do NOT instantiate this class directly, use - * getInstanceOf() instead. (Singleton pattern!) - * - */ - public WebConfig() { - - register(m_scheme); - register(m_server); - register(m_secureServer); - register(m_site); - register(m_host); - register(m_secureRequired); - register(m_secureSwitchBack); - register(m_servlet); - register(m_resolver); - register(m_deactivate_cache_host_notifications); - register(m_dynamic_host_provider); - - loadInfo(); - } - - public final String getDefaultScheme() { - return (String) get(m_scheme); - } - - public final HttpHost getServer() { - return (HttpHost) get(m_server); - } - - public final HttpHost getSecureServer() { - return (HttpHost) get(m_secureServer); - } - - public final boolean isSecureRequired(String uri) { - String[] secured = (String[]) get(m_secureRequired); - if (secured != null) { - for (int i = 0, n = secured.length; i < n; i++) { - if (uri.startsWith(secured[i])) { - return true; - } - } - } - return false; - } - - public final boolean isNonSecureSwitchRequired(String uri) { - String[] switchBack = (String[]) get(m_secureSwitchBack); - if (switchBack != null) { - for (int i = 0, n = switchBack.length; i < n; i++) { - if (uri.startsWith(switchBack[i])) { - return true; - } - } - } - return false; - } - - public final String getDispatcherServletPath() { - return (String) get(m_servlet); - } - - public final ApplicationFileResolver getApplicationFileResolver() { - return (ApplicationFileResolver) get(m_resolver); - } - - public final HttpHost getHost() { - return (HttpHost) get(m_host); - } - - final void setHost(final HttpHost host) { - set(m_host, host); - } - - public final String getSiteName() { - return (String) get(m_site); - } - - /** - * - * @return - * @deprecated use Web.getContextPath() instead. The installation context - * must no longer manually configured - */ - // NO LONGER configured by configuration option but determined at runtime - // by CCMDispatcherServlet itself. - // // dispatcherContextPath option in old Initializer, set to "" - // m_context = new StringParameter - // ("waf.web.dispatcher_context_path", Parameter.REQUIRED, ""); - public final String getDispatcherContextPath() { - // return (String) get(m_context); - return CCMDispatcherServlet.getContextPath(); - } - - - private static class DispatcherServletPathParameter - extends StringParameter { - - DispatcherServletPathParameter(final String name) { - super(name); - } - - @Override - protected void doValidate(final Object value, final ErrorList errors) { - final String string = (String) value; - - if (string.endsWith("/")) { - final ParameterError error = new ParameterError(this, - "The value must not end in a '/'"); - errors.add(error); + public void setDefaultScheme(final String defaultScheme) { + this.defaultScheme = defaultScheme; + } + + public String getServer() { + return server; + } + + public void setServer( + @Pattern(regexp = "[\\w-.]*:[0-9]{1,5}") final String server) { + final Method method; + try { + method = getClass().getMethod("setServer", String.class); + } catch (NoSuchMethodException ex) { + throw new UncheckedWrapperException(ex); + } + + final Set> violations + = validateHostParameter( + method, server); + + if (violations.isEmpty()) { + this.server = server; + } else { + final StringJoiner joiner = new StringJoiner(", "); + violations.forEach(v -> joiner.add(v.getMessage())); + + throw new IllegalArgumentException(joiner.toString()); + } + } + + public String getSecureServer() { + return secureServer; + } + + public void setSecureServer( + @Pattern(regexp = "[\\w-.]*:[0-9]{1,5}") final String secureServer) { + final Method method; + try { + method = getClass().getMethod("setSecureServer", String.class); + } catch (NoSuchMethodException ex) { + throw new UncheckedWrapperException(ex); + } + + final Set> violations + = validateHostParameter( + method, secureServer); + + if (violations.isEmpty()) { + this.secureServer = secureServer; + } else { + final StringJoiner joiner = new StringJoiner(", "); + violations.forEach(v -> joiner.add(v.getMessage())); + + throw new IllegalArgumentException(joiner.toString()); + } + } + + public String getSiteName() { + return siteName; + } + + public void setSiteName(final String siteName) { + this.siteName = siteName; + } + + public String getHost() { + return host; + } + + public void setHost( + @Pattern(regexp = "[\\w-.]*:[0-9]{1,5}") final String host) { + + final Method method; + try { + method = getClass().getMethod("setHost", String.class); + } catch (NoSuchMethodException ex) { + throw new UncheckedWrapperException(ex); + } + + final Set> violations + = validateHostParameter( + method, host); + + if (violations.isEmpty()) { + this.host = host; + } else { + final StringJoiner joiner = new StringJoiner(", "); + violations.forEach(v -> joiner.add(v.getMessage())); + + throw new IllegalArgumentException(joiner.toString()); + } + } + + public Set getSecureRequiredFor() { + return new HashSet<>(secureRequiredFor); + } + + public void setSecureRequiredFor(final Set secureRequiredFor) { + this.secureRequiredFor = secureRequiredFor; + } + + public String getDispatcherServletPath() { + return dispatcherServletPath; + } + + public void setDispatcherServletPath(final String dispatcherServletPath) { + this.dispatcherServletPath = dispatcherServletPath; + } + + public String getResolverClass() { + return resolverClass; + } + + public ApplicationFileResolver getResolver() { + try { + @SuppressWarnings("unchecked") + final Class clazz + = (Class) Class + .forName(resolverClass); + return clazz.newInstance(); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) { + throw new UncheckedWrapperException( + "Unable to retrieve ApplicationFileResolver", ex); + } + } + + public void setResolverClass(final String resolverClass) { + try { + final Class clazz = Class.forName(resolverClass); + if (!ApplicationFileResolver.class.isAssignableFrom(clazz)) { + throw new IllegalArgumentException( + String.format("Provided class \"%s\" is not an " + + "implementation of the interface \"%s\".", + resolverClass, + ApplicationFileResolver.class.getName())); } + } catch (ClassNotFoundException ex) { + throw new IllegalArgumentException( + String.format("Unable to retrieve class \"%s\".", + resolverClass), + ex); } + this.resolverClass = resolverClass; } - private static class DefaultSchemeParameter extends EnumerationParameter { - - DefaultSchemeParameter(final String name, - final int multiplicity, - final Object defaalt) { - super(name, multiplicity, defaalt); - - put("http", "http"); - put("https", "https"); - } - + public Boolean getDeactiveCacheHostNotifications() { + return deactiveCacheHostNotifications; } - protected DynamicHostProvider dhProvider = null; - protected boolean dhProviderInited = false; - - public final DynamicHostProvider getDynamicHostProvider() { - if (dhProviderInited == false) { - String classname = (String) get(m_dynamic_host_provider); - if (classname != null) { - try { - Class klass = Class.forName(classname); - dhProvider = (DynamicHostProvider) klass.newInstance(); - } catch (Exception e) { - LOGGER.error( - "Could not instantiate DynamicHostProvider using classname : " - + classname, e); - } - } - dhProviderInited = true; - } - return dhProvider; + public void setDeactiveCacheHostNotifications( + final Boolean deactiveCacheHostNotifications) { + this.deactiveCacheHostNotifications = deactiveCacheHostNotifications; } - public final boolean getDeactivateCacheHostNotifications() { - return ((Boolean) get(m_deactivate_cache_host_notifications)) - .booleanValue(); + public String getDynamicHostProvider() { + return dynamicHostProvider; + } + + public void setDynamicHostProvider(final String dynamicHostProvider) { + this.dynamicHostProvider = dynamicHostProvider; + } + + private Set> validateHostParameter( + final Method method, + final String parameter) { + final Object[] parameters = new Object[1]; + parameters[0] = parameter; + + final ValidatorFactory factory = Validation + .buildDefaultValidatorFactory(); + final ExecutableValidator validator = factory.getValidator() + .forExecutables(); + return validator.validateParameters(this, method, parameters); } } diff --git a/ccm-core/src/main/java/com/arsdigita/workflow/simple/WorkflowConfig.java b/ccm-core/src/main/java/com/arsdigita/workflow/simple/WorkflowConfig.java index 95b2fde32..3a40dbbfc 100755 --- a/ccm-core/src/main/java/com/arsdigita/workflow/simple/WorkflowConfig.java +++ b/ccm-core/src/main/java/com/arsdigita/workflow/simple/WorkflowConfig.java @@ -1,93 +1,102 @@ /* - * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. + * Copyright (C) 2016 LibreCCM Foundation. * * This library 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. + * 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 library 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 + * 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 library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA */ package com.arsdigita.workflow.simple; -import com.arsdigita.runtime.AbstractConfig; -import com.arsdigita.util.parameter.BooleanParameter; -import com.arsdigita.util.parameter.Parameter; -import com.arsdigita.util.parameter.StringParameter; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.configuration.Configuration; +import org.libreccm.configuration.ConfigurationManager; +import org.libreccm.configuration.Setting; + +import java.util.Objects; /** - * WorkflowConfig * - * @author Rafael H. Schloming <rhs@mit.edu> - * @version $Id: WorkflowConfig.java 287 2005-02-22 00:29:02Z sskracic $ + * @author Jens Pelzetter */ -public final class WorkflowConfig extends AbstractConfig { +@Configuration +public final class WorkflowConfig { - /** Private Object to hold one's own instance to return to users. */ - private static WorkflowConfig s_config; + @Setting + private Boolean simpleAlertsEnabled = true; - /** - * Returns the singleton configuration record for the workflow - * configuration. - * - * @return The ContentSectionConfig record; it cannot be null - */ - public static synchronized WorkflowConfig getInstance() { - if (s_config == null) { - s_config = new WorkflowConfig(); - s_config.load(); - } + @Setting + private String alertsSender; - return s_config; + public static WorkflowConfig getConfig() { + final CdiUtil cdiUtil = new CdiUtil(); + final ConfigurationManager confManager = cdiUtil.findBean( + ConfigurationManager.class); + return confManager.findConfiguration(WorkflowConfig.class); } - -// ///////////////////////////////////////////////////////////////////////////// -// -// Set of parameters controlling workflow alerts. -// -// ///////////////////////////////////////////////////////////////////////////// - - /** Turn on or off workflow alerts. */ - private BooleanParameter m_alerts = new BooleanParameter - ("waf.workflow.simple.alerts_enabled", Parameter.OPTIONAL, - Boolean.TRUE); - - /** Default sender for workflow alerts, e.g. workflow@example.com */ - private StringParameter m_sender = new StringParameter - ("waf.workflow.simple.alerts_sender", Parameter.OPTIONAL, null); - - /** - * Constructor - */ - public WorkflowConfig() { - register(m_alerts); - register(m_sender); - loadInfo(); + public Boolean getSimpleAlertsEnabled() { + return simpleAlertsEnabled; } - /** - * Retrieve whether alerts are to be enabled or not. - * @return true if alerts are enabled. - */ - public boolean isAlertsEnabled() { - return get(m_alerts).equals(Boolean.TRUE); + public void setSimpleAlertsEnabled(final Boolean simpleAlertsEnabled) { + this.simpleAlertsEnabled = simpleAlertsEnabled; } - /** - * Retrieve alert senders default mail address. - * @return - */ public String getAlertsSender() { - return (String) get(m_sender); + return alertsSender; + } + + public void setAlertsSender(final String alertsSender) { + this.alertsSender = alertsSender; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 47 * hash + Objects.hashCode(simpleAlertsEnabled); + hash = 47 * hash + Objects.hashCode(alertsSender); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (obj instanceof WorkflowConfig) { + return false; + } + final WorkflowConfig other = (WorkflowConfig) obj; + if (!Objects.equals(alertsSender, other.getAlertsSender())) { + return false; + } + return Objects.equals(simpleAlertsEnabled, other + .getSimpleAlertsEnabled()); + } + + @Override + public String toString() { + return String.format("%s{ " + + "simpleAlertsEnabled = %b, " + + "alertsSender = %s" + + " }", + super.toString(), + simpleAlertsEnabled, + alertsSender); } } diff --git a/ccm-core/src/main/resources/com/arsdigita/templating/TemplatingConfigDescription.properties b/ccm-core/src/main/resources/com/arsdigita/templating/TemplatingConfigDescription.properties new file mode 100644 index 000000000..81df08a5e --- /dev/null +++ b/ccm-core/src/main/resources/com/arsdigita/templating/TemplatingConfigDescription.properties @@ -0,0 +1,31 @@ +# Copyright (C) 2016 LibreCCM Foundation. +# +# This library 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 library 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 library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA + +description = Configuration parameters for the (XSL-) Templating system + +stylesheetPaths.label = Stylesheet paths file +stylesheetPaths.description = PatternStylesheetResolver uses this file to match a request to a stylesheet + +stylesheetResolverClass.label = Stylesheet resolver class +stylesheetResolverClass.description = Specifies a particular implementation of StylesheetResolver interface + +stylesheetCacheSize.label = Stylesheet cache size +stylesheetCacheSize.description = Set the number of stylesheets cached + +stylesheetCacheAge.label = Stylesheet cache age +stylesheetCacheAge.description = Set the duration of the stylesheet cache, in seconds + diff --git a/ccm-core/src/main/resources/com/arsdigita/templating/TemplatingConfig_parameter.properties b/ccm-core/src/main/resources/com/arsdigita/templating/TemplatingConfig_parameter.properties deleted file mode 100755 index 774fce44c..000000000 --- a/ccm-core/src/main/resources/com/arsdigita/templating/TemplatingConfig_parameter.properties +++ /dev/null @@ -1,16 +0,0 @@ -waf.templating.stylesheet_paths.title=Stylesheet paths file -waf.templating.stylesheet_paths.purpose=PatternStylesheetResolver uses this file to match a request to a stylesheet -waf.templating.stylesheet_paths.example=/WEB-INF/resources/stylesheet-paths.txt -waf.templating.stylesheet_paths.format=[string] -waf.templating.stylesheet_resolver.title=Stylesheet resolver class -waf.templating.stylesheet_resolver.purpose=Specifies a particular implementation of StylesheetResolver interface -waf.templating.stylesheet_resolver.example=com.arsdigita.templating.PatternStylesheetResolver -waf.templating.stylesheet_resolver.format=[classname] -waf.templating.stylesheet_cache_size.title=Stylesheet cache size -waf.templating.stylesheet_cache_size.purpose=Set the number of stylesheets cached -waf.templating.stylesheet_cache_size.example=10 -waf.templating.stylesheet_cache_size.format=[integer] -waf.templating.stylesheet_cache_age.title=Stylesheet cache age -waf.templating.stylesheet_cache_age.purpose=Set the duration of the stylesheet cache, in seconds -waf.templating.stylesheet_cache_age.example=3600 -waf.templating.stylesheet_cache_age.format=[integer] diff --git a/ccm-core/src/main/resources/com/arsdigita/workflow/simple/WorkflowConfigDescription.properties b/ccm-core/src/main/resources/com/arsdigita/workflow/simple/WorkflowConfigDescription.properties new file mode 100644 index 000000000..d086f4a13 --- /dev/null +++ b/ccm-core/src/main/resources/com/arsdigita/workflow/simple/WorkflowConfigDescription.properties @@ -0,0 +1,25 @@ +# Copyright (C) 2016 LibreCCM Foundation. +# +# This library 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 library 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 library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA + +description = Configuration properties for the Workflow system + +simpleAlertsEnabled.label = Workflow Alerts Enabled +simpleAlertsEnabled.description = Turn on and off workflow alerts + +alertsSender.label = Workflow Alerts Sender +alertsSender.description = Default sender for workflow alerts, eg workflow@example.org + diff --git a/ccm-core/src/main/resources/com/arsdigita/workflow/simple/WorkflowConfig_parameter.properties b/ccm-core/src/main/resources/com/arsdigita/workflow/simple/WorkflowConfig_parameter.properties deleted file mode 100755 index b83ba779e..000000000 --- a/ccm-core/src/main/resources/com/arsdigita/workflow/simple/WorkflowConfig_parameter.properties +++ /dev/null @@ -1,8 +0,0 @@ -waf.workflow.simple.alerts_enabled.title=Workflow Alerts Enabled -waf.workflow.simple.alerts_enabled.purpose=Turn on and off workflow alerts -waf.workflow.simple.alerts_enabled.example=true -waf.workflow.simple.alerts_enabled.format=true|false -waf.workflow.simple.alerts_sender.title=Workflow Alerts Sender -waf.workflow.simple.alerts_sender.purpose=Default sender for workflow alerts -waf.workflow.simple.alerts_sender.example=workflow@example.com -waf.workflow.simple.alerts_sender.format=[email] \ No newline at end of file diff --git a/ccm-core/src/test/java/com/arsdigita/web/WebConfigTest.java b/ccm-core/src/test/java/com/arsdigita/web/WebConfigTest.java new file mode 100644 index 000000000..5814a3c91 --- /dev/null +++ b/ccm-core/src/test/java/com/arsdigita/web/WebConfigTest.java @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library 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 library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.web; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.libreccm.tests.categories.UnitTest; + +import java.util.ArrayList; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +/** + * + * @author Jens Pelzetter + */ +@Category(UnitTest.class) +public class WebConfigTest { + + public WebConfigTest() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + @Test + public void setValidResolver() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setResolverClass(DefaultApplicationFileResolver.class + .getName()); + + assertThat(webConfig.getResolverClass(), + is(equalTo(DefaultApplicationFileResolver.class.getName()))); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidResolver() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setResolverClass(ArrayList.class.getName()); + + } + + @Test(expected = IllegalArgumentException.class) + public void setNotExistingResolver() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setResolverClass("org.example.resolvers.NotExisting"); + } + + @Test + public void setValidHost() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setHost("zeus.example.org:8080"); + + assertThat(webConfig.getHost(), + is(equalTo("zeus.example.org:8080"))); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidHostWithSchema() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setHost("http://zeus.example.org:8080"); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidHostWithoutPort() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setHost("http://zeus.example.org"); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidHostLongPort() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setHost("http://zeus.example.org:999999"); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidHostWithPath() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setHost("http://zeus.example.org:8080/foo"); + } + + @Test + public void setValidServer() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setServer("zeus.example.org:8080"); + + assertThat(webConfig.getServer(), + is(equalTo("zeus.example.org:8080"))); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidServerWithSchema() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setServer("http://zeus.example.org:8080"); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidServerWithoutPort() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setServer("http://zeus.example.org"); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidServerLongPort() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setServer("http://zeus.example.org:999999"); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidServerWithPath() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setServer("http://zeus.example.org:8080/foo"); + } + + @Test + public void setValidSecureServer() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setSecureServer("zeus.example.org:8080"); + + assertThat(webConfig.getSecureServer(), + is(equalTo("zeus.example.org:8080"))); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidSecureServerWithSchema() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setSecureServer("http://zeus.example.org:8080"); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidSecureServerWithoutPort() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setSecureServer("http://zeus.example.org"); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidSecureLongPort() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setSecureServer("http://zeus.example.org:999999"); + } + + @Test(expected = IllegalArgumentException.class) + public void setInvalidSecureServerWithPath() { + final WebConfig webConfig = new WebConfig(); + + webConfig.setSecureServer("http://zeus.example.org:8080/foo"); + } + +}