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
pull/2/head
jensp 2016-01-19 19:08:51 +00:00
parent 1a3367bbed
commit 127ff16e59
14 changed files with 1192 additions and 772 deletions

View File

@ -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;
}
}
}

View File

@ -43,15 +43,15 @@ import org.apache.log4j.Logger;
/** /**
* <p> * <p>
* This stylesheet resolver is used by the <code>*PresentationManager</code> * This stylesheet resolver is used by the <code>*PresentationManager</code>
* class to work out which XSLT stylesheet to apply to the current Bebop * class to work out which XSLT stylesheet to apply to the current Bebop XML
* XML output. * output.
* </p> * </p>
* *
* <p> * <p>
* This particular stylesheet resolver uses a flat file containing a list * This particular stylesheet resolver uses a flat file containing a list of
* of stylesheet patterns, one per line. The file is called * stylesheet patterns, one per line. The file is called
* <code>WEB-INF/resources/stylesheet-paths.txt</code>. * <code>WEB-INF/resources/stylesheet-paths.txt</code>. Such a file could look
* Such a file could look like this: * like this:
* </p> * </p>
* *
* <pre> * <pre>
@ -71,8 +71,8 @@ import org.apache.log4j.Logger;
* </p> * </p>
* *
* <p> * <p>
* The patterns, such as <code>::vhost::</code>, are substituted * The patterns, such as <code>::vhost::</code>, are substituted for string
* for string values: * values:
* </p> * </p>
* *
* <table border="1"> * <table border="1">
@ -141,37 +141,37 @@ import org.apache.log4j.Logger;
* actually exists on disk is returned. * actually exists on disk is returned.
* </p> * </p>
* *
* Developer may customize the process by writing a custom pattern generator * Developer may customize the process by writing a custom pattern generator and
* and add it in a custom integration package Initializer (e.g. ccm-ldn-aplaws) * add it in a custom integration package Initializer (e.g. ccm-ldn-aplaws) by
* by following code: * following code: // Register additional PatternStyleSheetResolver for Web app.
* // Register additional PatternStyleSheetResolver for Web app. * PatternStylesheetResolver.registerPatternGenerator( "[myKey]", new
* PatternStylesheetResolver.registerPatternGenerator( * [My]PatternGenerator() );
* "[myKey]",
* new [My]PatternGenerator()
* );
* *
* *
* @author Richard W.M. Jones * @author Richard W.M. Jones
*/ */
public class PatternStylesheetResolver implements StylesheetResolver { 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 * Internal logger instance to faciliate debugging. Enable logging output by
* and set com.arsdigita.templating.PatternStylesheetResolver=DEBUG * editing /WEB-INF/conf/log4j.properties int the runtime environment and
* by uncommenting or adding the line. */ * set com.arsdigita.templating.PatternStylesheetResolver=DEBUG by
private static final Logger s_log = Logger.getLogger * uncommenting or adding the line.
(PatternStylesheetResolver.class); */
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(); private static final HashMap s_generators = new HashMap();
/** /**
* Registers a new pattern generator for the given key. * Registers a new pattern generator for the given key.
* *
* @param key the key as it appears in the pattern string * @param key the key as it appears in the pattern string
* @param gen a pattern generator for producing values to be * @param gen a pattern generator for producing values to be substituted for
* substituted for <code>key</code> * <code>key</code>
*/ */
public static void registerPatternGenerator(String key, public static void registerPatternGenerator(String key,
PatternGenerator gen) { PatternGenerator gen) {
@ -182,34 +182,33 @@ public class PatternStylesheetResolver implements StylesheetResolver {
* at load time. */ * at load time. */
static { static {
s_log.debug("Static initalizer starting..."); s_log.debug("Static initalizer starting...");
registerPatternGenerator registerPatternGenerator("locale", new LocalePatternGenerator());
("locale", new LocalePatternGenerator()); registerPatternGenerator("url", new URLPatternGenerator());
registerPatternGenerator registerPatternGenerator("application",
("url", new URLPatternGenerator()); new ApplicationPatternGenerator());
registerPatternGenerator registerPatternGenerator("outputtype", new OutputTypePatternGenerator());
("application", new ApplicationPatternGenerator()); registerPatternGenerator("prefix", new PrefixPatternGenerator());
registerPatternGenerator registerPatternGenerator("webapp", new WebAppPatternGenerator());
("outputtype", new OutputTypePatternGenerator()); registerPatternGenerator("host", new HostPatternGenerator());
registerPatternGenerator
("prefix", new PrefixPatternGenerator());
registerPatternGenerator
("webapp", new WebAppPatternGenerator());
registerPatternGenerator
("host", new HostPatternGenerator());
s_log.debug("Static initalizer finished."); 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; 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 * A List of Lists each of its lists containing one pattern to resolve a
* file m_path above) */ * probably appropriate stylesheet to apply. (i.e. one row of the file
* m_path above)
*/
private List m_paths = null; private List m_paths = null;
/** /**
* *
* @param request * @param request
*
* @return * @return
*/ */
@Override @Override
@ -288,13 +287,13 @@ public class PatternStylesheetResolver implements StylesheetResolver {
} }
// fall through & try next pattern // fall through & try next pattern
} catch (IOException ex) { } catch (IOException ex) {
throw new UncheckedWrapperException("cannot open stream " + throw new UncheckedWrapperException("cannot open stream "
resource, ex); + resource, ex);
} }
} }
throw new RuntimeException("no path to XSL stylesheet found; " + throw new RuntimeException("no path to XSL stylesheet found; "
"try modifying " + m_path); + "try modifying " + m_path);
} }
/** /**
@ -342,8 +341,8 @@ public class PatternStylesheetResolver implements StylesheetResolver {
} }
} }
if (s_log.isDebugEnabled()) { if (s_log.isDebugEnabled()) {
s_log.debug("Requeue " + s_log.debug("Requeue " + StringUtils.join(
StringUtils.join(newBits, "")); newBits, ""));
} }
queue.add(newBits); queue.add(newBits);
} }
@ -353,8 +352,8 @@ public class PatternStylesheetResolver implements StylesheetResolver {
if (clean) { if (clean) {
if (s_log.isDebugEnabled()) { if (s_log.isDebugEnabled()) {
s_log.debug("Finished expanding placeholders in " + s_log.debug("Finished expanding placeholders in "
StringUtils.join(bits, "")); + StringUtils.join(bits, ""));
} }
paths.add(bits); paths.add(bits);
} }
@ -366,6 +365,7 @@ public class PatternStylesheetResolver implements StylesheetResolver {
* @param key * @param key
* @param values * @param values
* @param request * @param request
*
* @return * @return
*/ */
private String[] getValues(String key, private String[] getValues(String key,
@ -404,8 +404,8 @@ public class PatternStylesheetResolver implements StylesheetResolver {
s_log.debug("stream.available is " + stream.available()); s_log.debug("stream.available is " + stream.available());
m_paths = new ArrayList(); m_paths = new ArrayList();
LineNumberReader file = new LineNumberReader LineNumberReader file = new LineNumberReader(new InputStreamReader(
(new InputStreamReader(stream)); stream));
String line; String line;
int lineNum; int lineNum;
while ((line = file.readLine()) != null) { while ((line = file.readLine()) != null) {

View File

@ -77,7 +77,7 @@ public class Templating {
* Config object containing various parameter * Config object containing various parameter
*/ */
private static final TemplatingConfig s_config = TemplatingConfig private static final TemplatingConfig s_config = TemplatingConfig
.getInstanceOf(); .getConfig();
static { static {
s_log.debug("Static initalizer starting..."); s_log.debug("Static initalizer starting...");
@ -91,24 +91,25 @@ public class Templating {
TransformerException ex = (TransformerException) t; TransformerException ex = (TransformerException) t;
return ex.getCause(); return ex.getCause();
} }
}); });
// now we initiate the CacheTable here // now we initiate the CacheTable here
// default cache size used to be 50, which is too high I reckon, // default cache size used to be 50, which is too high I reckon,
// each template can eat up to 4 megs // 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()); 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()); int cacheAge = (setting == null ? 60 * 60 * 24 * 3 : setting.intValue());
s_log.debug("Static initalizer finished..."); s_log.debug("Static initalizer finished...");
} }
/** /**
* Gets the <code>TemplatingConfig</code> record. * Gets the <code>LegacyTemplatingConfig</code> record.
* *
* @return The <code>TemplatingConfig</code> of this runtime * @return The <code>LegacyTemplatingConfig</code> of this runtime
*/ */
public static TemplatingConfig getConfig() { public static TemplatingConfig getConfig() {
return s_config; return s_config;
@ -151,6 +152,7 @@ public class Templating {
* was first generated, it will be regenerated first. * was first generated, it will be regenerated first.
* *
* @param source the <code>URL</code> to the top-level template resource * @param source the <code>URL</code> to the top-level template resource
*
* @return an <code>XSLTemplate</code> instance representing * @return an <code>XSLTemplate</code> instance representing
* <code>source</code> * <code>source</code>
*/ */
@ -163,13 +165,16 @@ public class Templating {
* cache, it will be returned. If the template has been modified since it * cache, it will be returned. If the template has been modified since it
* was first generated, it will be regenerated first. * was first generated, it will be regenerated first.
* *
* @param source the <code>URL</code> to the top-level template resource * @param source the <code>URL</code> to the top-level template
* resource
* @param fancyErrors Should this place any xsl errors in the request for * @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 * use by another class. If this is true, the the errors
* later use. * are stored for later use.
* @param useCache Should the templates be pulled from cache, if available? * @param useCache Should the templates be pulled from cache, if
* True means they are pulled from cache. False means they are pulled from * available? True means they are pulled from cache.
* the disk. If this is false the pages are also not placed in the cache. * False means they are pulled from the disk. If this is
* false the pages are also not placed in the cache.
*
* @return an <code>XSLTemplate</code> instance representing * @return an <code>XSLTemplate</code> instance representing
* <code>source</code> * <code>source</code>
*/ */
@ -228,6 +233,7 @@ public class Templating {
* Resolves and retrieves the template for the given request. * Resolves and retrieves the template for the given request.
* *
* @param sreq The current request object * @param sreq The current request object
*
* @return The resolved <code>XSLTemplate</code> instance * @return The resolved <code>XSLTemplate</code> instance
*/ */
public static XSLTemplate getTemplate(final HttpServletRequest sreq) { public static XSLTemplate getTemplate(final HttpServletRequest sreq) {
@ -239,11 +245,13 @@ public class Templating {
* *
* @param sreq The current request object * @param sreq The current request object
* @param fancyErrors Should this place any xsl errors in the request for * @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 * use by another class. If this is true, the the errors
* later use. * are stored for later use.
* @param useCache Should the templates be pulled from cache, if available? * @param useCache Should the templates be pulled from cache, if
* True means they are pulled from cache. False means they are pulled from * available? True means they are pulled from cache.
* the disk. If this is false the pages are also not placed in the 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 <code>XSLTemplate</code> instance * @return The resolved <code>XSLTemplate</code> instance
*/ */
public static XSLTemplate getTemplate(final HttpServletRequest sreq, public static XSLTemplate getTemplate(final HttpServletRequest sreq,
@ -286,6 +294,7 @@ public class Templating {
* Generates a stream containing imports for a number of URLs. * Generates a stream containing imports for a number of URLs.
* *
* @param paths An iterator of <code>java.net.URL</code> objects * @param paths An iterator of <code>java.net.URL</code> objects
*
* @return a virtual XSL file * @return a virtual XSL file
*/ */
public static InputStream multiplexXSLFiles(Iterator paths) { public static InputStream multiplexXSLFiles(Iterator paths) {
@ -418,12 +427,15 @@ public class Templating {
} }
} else // url is not the (local) running CCM host, no transformation } else // url is not the (local) running CCM host, no transformation
// is done // is done
{
if (s_log.isDebugEnabled()) { if (s_log.isDebugEnabled()) {
s_log.debug("URL " + url + " is not local"); s_log.debug("URL " + url + " is not local");
} }
}
return url; // returns the original, unmodified url here return url; // returns the original, unmodified url here
} }
} }
/** /**
@ -433,7 +445,8 @@ public class Templating {
class LoggingErrorListener implements ErrorListener { class LoggingErrorListener implements ErrorListener {
private static final Logger s_log private static final Logger s_log
= Logger.getLogger(LoggingErrorListener.class); = Logger.getLogger(
LoggingErrorListener.class);
private final ArrayList m_errors; private final ArrayList m_errors;
LoggingErrorListener() { LoggingErrorListener() {
@ -466,4 +479,5 @@ class LoggingErrorListener implements ErrorListener {
ex); ex);
m_errors.add(ex); m_errors.add(ex);
} }
} }

View File

@ -1,10 +1,10 @@
/* /*
* 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public
* as published by the Free Software Foundation; either version 2.1 of * License as published by the Free Software Foundation; either
* the License, or (at your option) any later version. * 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, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -13,110 +13,165 @@
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * 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; package com.arsdigita.templating;
import com.arsdigita.runtime.AbstractConfig; import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.util.parameter.Parameter; import com.arsdigita.web.ApplicationFileResolver;
import com.arsdigita.util.parameter.IntegerParameter;
import com.arsdigita.util.parameter.SingletonParameter; import org.libreccm.cdi.utils.CdiUtil;
import com.arsdigita.util.parameter.StringParameter; import org.libreccm.configuration.Configuration;
import org.apache.log4j.Logger; import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.configuration.Setting;
import java.util.Objects;
/** /**
* @author Justin Ross
* @version $Id$
*/
public final class TemplatingConfig extends AbstractConfig {
/** 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);
/** Singelton config object. */
private static TemplatingConfig s_conf;
/**
* Gain a WorkspaceConfig object.
* *
* Singelton pattern, don't instantiate a config object using the * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* constructor directly!
* @return
*/ */
public static synchronized TemplatingConfig getInstanceOf() { @Configuration
if (s_conf == null) { public final class TemplatingConfig {
s_conf = new TemplatingConfig();
s_conf.load(); @Setting
private String stylesheetPaths = "/WEB-INF/resources/stylesheet-paths.txt";
@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);
} }
return s_conf; public String getStylesheetPaths() {
return stylesheetPaths;
} }
/** Fully qualified path string to file contain the pattern file for public void setStylesheetPaths(final String stylesheetPaths) {
{@link com.arsdigita.templating.PatternStylesheetResolver this.stylesheetPaths = stylesheetPaths;
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 String getStylesheetResolverClass() {
* Get name and location of stylesheet pattern file. return stylesheetResolverClass;
*
* @return String with fully qualified file name
*/
final String getStylesheetPaths() {
return (String) get(m_paths);
} }
/** public StylesheetResolver getStylesheetResolver() {
* Gets the stylesheet resolver. This value is set via the
* <code>com.arsdigita.templating.stylesheet_resolver</code> try {
* system property. @SuppressWarnings("unchecked")
* @return final Class<StylesheetResolver> clazz
*/ = (Class<StylesheetResolver>) Class
public final StylesheetResolver getStylesheetResolver() { .forName(stylesheetResolverClass);
return (StylesheetResolver) get(m_resolver); return clazz.newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
throw new UncheckedWrapperException(
"Unable to create configured StylesheetResolver.",
ex);
}
} }
/** Can be null. public void setStylesheetResolverClass(
* @return */ final String stylesheetResolverClass) {
public final Integer getCacheSize() { try {
return (Integer) get(m_cacheSize); 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);
} }
/** Can be null. this.stylesheetResolverClass = stylesheetResolverClass;
* @return */
public final Integer getCacheAge() {
return (Integer) get(m_cacheAge);
} }
public Integer getStylesheetCacheSize() {
return stylesheetCacheSize;
}
public void setStylesheetCacheSize(final Integer stylesheetCacheSize) {
this.stylesheetCacheSize = stylesheetCacheSize;
}
public Integer getStylesheetCacheAge() {
return stylesheetCacheAge;
}
public void setStylesheetCacheAge(final Integer stylesheetCacheAge) {
this.stylesheetCacheAge = stylesheetCacheAge;
}
@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);
}
} }

View File

@ -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 &lt;jross@redhat.com&gt;
* @author <a href="jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
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 <code>CMSConfig</code> 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();
}
}

View File

@ -120,7 +120,7 @@ import org.libreccm.web.CcmApplication;
* *
* <p> * <p>
* Those methods not taking an <code>HttpServletRequest</code> use the scheme, * Those methods not taking an <code>HttpServletRequest</code> use the scheme,
* server name, and port defined in <code>WebConfig</code>.</p> * server name, and port defined in <code>LegacyWebConfig</code>.</p>
* *
* <p> * <p>
* All static create methods taking a <code>ParameterMap</code> take null to * All static create methods taking a <code>ParameterMap</code> take null to
@ -136,7 +136,7 @@ import org.libreccm.web.CcmApplication;
* @see com.arsdigita.web.DispatcherServlet * @see com.arsdigita.web.DispatcherServlet
* @see com.arsdigita.web.LoginSignal * @see com.arsdigita.web.LoginSignal
* @see com.arsdigita.web.ReturnSignal * @see com.arsdigita.web.ReturnSignal
* @see com.arsdigita.web.WebConfig * @see com.arsdigita.web.LegacyWebConfig
* @see com.arsdigita.web.Application * @see com.arsdigita.web.Application
* @author Justin Ross * @author Justin Ross
* &lt;<a href="mailto:jross@redhat.com">jross@redhat.com</a>&gt; * &lt;<a href="mailto:jross@redhat.com">jross@redhat.com</a>&gt;
@ -612,7 +612,7 @@ public class URL {
* @return a <code>URL</code> to your server's root path * @return a <code>URL</code> to your server's root path
*/ */
public static final URL root() { public static final URL root() {
final WebConfig config = Web.getConfig(); final LegacyWebConfig config = Web.getConfig();
URL url = new URL(config.getDefaultScheme(), URL url = new URL(config.getDefaultScheme(),
config.getServer().getName(), config.getServer().getName(),
@ -679,7 +679,7 @@ public class URL {
public static final URL there(final HttpServletRequest sreq, public static final URL there(final HttpServletRequest sreq,
final String path, final String path,
final ParameterMap params) { final ParameterMap params) {
final WebConfig config = Web.getConfig(); final LegacyWebConfig config = Web.getConfig();
Assert.exists(sreq, "HttpServletRequest sreq"); Assert.exists(sreq, "HttpServletRequest sreq");
Assert.exists(config, "WebConfig config"); Assert.exists(config, "WebConfig config");
@ -715,7 +715,7 @@ public class URL {
public static final URL dynamicHostThere(final HttpServletRequest sreq, public static final URL dynamicHostThere(final HttpServletRequest sreq,
final String path, final String path,
final ParameterMap params) { final ParameterMap params) {
final WebConfig config = Web.getConfig(); final LegacyWebConfig config = Web.getConfig();
DynamicHostProvider provider = Web.getConfig().getDynamicHostProvider(); DynamicHostProvider provider = Web.getConfig().getDynamicHostProvider();
if (provider == null) { if (provider == null) {
@ -755,7 +755,7 @@ public class URL {
*/ */
public static final URL there(final HttpServletRequest sreq, public static final URL there(final HttpServletRequest sreq,
final String path) { final String path) {
final WebConfig config = Web.getConfig(); final LegacyWebConfig config = Web.getConfig();
Assert.exists(sreq, "HttpServletRequest sreq"); Assert.exists(sreq, "HttpServletRequest sreq");
Assert.exists(config, "WebConfig config"); Assert.exists(config, "WebConfig config");
@ -847,7 +847,7 @@ public class URL {
*/ */
public static final URL there(final String path, public static final URL there(final String path,
final ParameterMap params) { final ParameterMap params) {
final WebConfig config = Web.getConfig(); final LegacyWebConfig config = Web.getConfig();
return new URL(config.getDefaultScheme(), return new URL(config.getDefaultScheme(),
config.getServer().getName(), config.getServer().getName(),
@ -949,7 +949,7 @@ public class URL {
* @return * @return
*/ */
public static String getDispatcherPath() { public static String getDispatcherPath() {
final WebConfig config = Web.getConfig(); final LegacyWebConfig config = Web.getConfig();
final HttpServletRequest req = Web.getRequest(); final HttpServletRequest req = Web.getRequest();
final String context = config.getDispatcherContextPath(); final String context = config.getDispatcherContextPath();

View File

@ -47,7 +47,7 @@ public class Web {
*/ */
private static final Logger s_log = Logger.getLogger(Web.class); 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_request = new InternalRequestLocal();
private static final ThreadLocal s_servletContext private static final ThreadLocal s_servletContext
@ -90,9 +90,9 @@ public class Web {
/** /**
* Provide the configuration record for code in the web package. * Provide the configuration record for code in the web package.
* *
* @return A <code>WebConfig</code> configuration record; it cannot be null * @return A <code>LegacyWebConfig</code> configuration record; it cannot be null
*/ */
public static WebConfig getConfig() { public static LegacyWebConfig getConfig() {
return s_config; return s_config;
} }

View File

@ -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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -18,302 +18,250 @@
*/ */
package com.arsdigita.web; package com.arsdigita.web;
import com.arsdigita.runtime.AbstractConfig; import com.arsdigita.util.UncheckedWrapperException;
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.libreccm.cdi.utils.CdiUtil;
import org.apache.logging.log4j.Logger; import org.libreccm.configuration.Configuration;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.configuration.Setting;
/** import java.lang.reflect.Method;
* A record containing server-session scoped configuration properties. import java.util.HashSet;
* import java.util.Set;
* Accessors of this class may return null. Developers should take care to trap import java.util.StringJoiner;
* null return values in their code. import java.util.logging.Level;
* import java.util.logging.Logger;
* @see com.arsdigita.web.Web
* @author Justin Ross &lt;jross@redhat.com&gt;
* @author <a href="jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class WebConfig extends AbstractConfig {
private static final Logger LOGGER = LogManager.getLogger(WebConfig.class); import javax.validation.ConstraintViolation;
import javax.validation.Validation;
private static WebConfig config; import javax.validation.ValidatorFactory;
import javax.validation.constraints.Pattern;
/** import javax.validation.executable.ExecutableValidator;
* Returns the singleton configuration record for the content section
* environment.
*
* @return The <code>CMSConfig</code> record; it cannot be null
*/
public static synchronized WebConfig getInstanceOf() {
if (config == null) {
config = new WebConfig();
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 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 * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @deprecated use Web.getContextPath() instead. The installation context
* must no longer manually configured
*/ */
// NO LONGER configured by configuration option but determined at runtime @Configuration
// by CCMDispatcherServlet itself. public final class WebConfig {
// // dispatcherContextPath option in old Initializer, set to ""
// m_context = new StringParameter @Setting
// ("waf.web.dispatcher_context_path", Parameter.REQUIRED, ""); private String defaultScheme = "http";
public final String getDispatcherContextPath() {
// return (String) get(m_context); @Setting
return CCMDispatcherServlet.getContextPath(); private String server;
@Setting
private String secureServer;
@Setting
private String siteName;
@Setting
private String host;
@Setting
private Set<String> 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);
} }
public String getDefaultScheme() {
private static class DispatcherServletPathParameter return defaultScheme;
extends StringParameter {
DispatcherServletPathParameter(final String name) {
super(name);
} }
@Override public void setDefaultScheme(final String defaultScheme) {
protected void doValidate(final Object value, final ErrorList errors) { this.defaultScheme = defaultScheme;
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 String getServer() {
return server;
} }
private static class DefaultSchemeParameter extends EnumerationParameter { public void setServer(
@Pattern(regexp = "[\\w-.]*:[0-9]{1,5}") final String server) {
DefaultSchemeParameter(final String name, final Method method;
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 { try {
Class klass = Class.forName(classname); method = getClass().getMethod("setServer", String.class);
dhProvider = (DynamicHostProvider) klass.newInstance(); } catch (NoSuchMethodException ex) {
} catch (Exception e) { throw new UncheckedWrapperException(ex);
LOGGER.error(
"Could not instantiate DynamicHostProvider using classname : "
+ classname, e);
}
}
dhProviderInited = true;
}
return dhProvider;
} }
public final boolean getDeactivateCacheHostNotifications() { final Set<ConstraintViolation<WebConfig>> violations
return ((Boolean) get(m_deactivate_cache_host_notifications)) = validateHostParameter(
.booleanValue(); 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<ConstraintViolation<WebConfig>> 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<ConstraintViolation<WebConfig>> 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<String> getSecureRequiredFor() {
return new HashSet<>(secureRequiredFor);
}
public void setSecureRequiredFor(final Set<String> 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<ApplicationFileResolver> clazz
= (Class<ApplicationFileResolver>) 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;
}
public Boolean getDeactiveCacheHostNotifications() {
return deactiveCacheHostNotifications;
}
public void setDeactiveCacheHostNotifications(
final Boolean deactiveCacheHostNotifications) {
this.deactiveCacheHostNotifications = deactiveCacheHostNotifications;
}
public String getDynamicHostProvider() {
return dynamicHostProvider;
}
public void setDynamicHostProvider(final String dynamicHostProvider) {
this.dynamicHostProvider = dynamicHostProvider;
}
private Set<ConstraintViolation<WebConfig>> 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);
} }
} }

View File

@ -1,10 +1,10 @@
/* /*
* 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public
* as published by the Free Software Foundation; either version 2.1 of * License as published by the Free Software Foundation; either
* the License, or (at your option) any later version. * 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, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -13,81 +13,90 @@
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * 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; package com.arsdigita.workflow.simple;
import com.arsdigita.runtime.AbstractConfig; import org.libreccm.cdi.utils.CdiUtil;
import com.arsdigita.util.parameter.BooleanParameter; import org.libreccm.configuration.Configuration;
import com.arsdigita.util.parameter.Parameter; import org.libreccm.configuration.ConfigurationManager;
import com.arsdigita.util.parameter.StringParameter; import org.libreccm.configuration.Setting;
import java.util.Objects;
/** /**
* WorkflowConfig
* *
* @author Rafael H. Schloming &lt;rhs@mit.edu&gt; * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @version $Id: WorkflowConfig.java 287 2005-02-22 00:29:02Z sskracic $
*/ */
public final class WorkflowConfig extends AbstractConfig { @Configuration
public final class WorkflowConfig {
/** Private Object to hold one's own instance to return to users. */ @Setting
private static WorkflowConfig s_config; private Boolean simpleAlertsEnabled = true;
/** @Setting
* Returns the singleton configuration record for the workflow private String alertsSender;
* configuration.
* public static WorkflowConfig getConfig() {
* @return The <code>ContentSectionConfig</code> record; it cannot be null final CdiUtil cdiUtil = new CdiUtil();
*/ final ConfigurationManager confManager = cdiUtil.findBean(
public static synchronized WorkflowConfig getInstance() { ConfigurationManager.class);
if (s_config == null) { return confManager.findConfiguration(WorkflowConfig.class);
s_config = new WorkflowConfig();
s_config.load();
} }
return s_config; public Boolean getSimpleAlertsEnabled() {
return simpleAlertsEnabled;
} }
public void setSimpleAlertsEnabled(final Boolean simpleAlertsEnabled) {
// ///////////////////////////////////////////////////////////////////////////// this.simpleAlertsEnabled = simpleAlertsEnabled;
//
// 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();
} }
/**
* 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);
}
/**
* Retrieve alert senders default mail address.
* @return
*/
public String getAlertsSender() { 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);
} }
} }

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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]

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@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");
}
}