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>
* This stylesheet resolver is used by the <code>*PresentationManager</code>
* 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.
* </p>
*
* <p>
* This particular stylesheet resolver uses a flat file containing a list
* of stylesheet patterns, one per line. The file is called
* <code>WEB-INF/resources/stylesheet-paths.txt</code>.
* 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
* <code>WEB-INF/resources/stylesheet-paths.txt</code>. Such a file could look
* like this:
* </p>
*
* <pre>
@ -71,57 +71,57 @@ import org.apache.log4j.Logger;
* </p>
*
* <p>
* The patterns, such as <code>::vhost::</code>, are substituted
* for string values:
* The patterns, such as <code>::vhost::</code>, are substituted for string
* values:
* </p>
*
* <table border="1">
* <tr> <th> Pattern </th> <th> Meaning </th> <th> Examples </th> </tr>
* <tr>
* <td> <code>::host::</code> </td>
* <td> Host name </td>
* <td> <code>www.aplaws.org</code> </td>
* <td> <code>::host::</code> </td>
* <td> Host name </td>
* <td> <code>www.aplaws.org</code> </td>
* </tr>
* <tr>
* <td> <code>::vhost::</code> </td>
* <td> Virtual hostname. </td>
* <td> <code>business.camden.gov.uk</code> </td>
* <td> <code>::vhost::</code> </td>
* <td> Virtual hostname. </td>
* <td> <code>business.camden.gov.uk</code> </td>
* </tr>
* <tr>
* <td> <code>::webapp::</code> </td>
* <td> Current web application name (ie. context or document root) </td>
* <td> <code>ccm</code> </td>
* <td> <code>::webapp::</code> </td>
* <td> Current web application name (ie. context or document root) </td>
* <td> <code>ccm</code> </td>
* </tr>
* <tr>
* <td> <code>::application::</code> </td>
* <td> Current CCM Application name </td>
* <td> <code>navigation</code> </td>
* <td> <code>::application::</code> </td>
* <td> Current CCM Application name </td>
* <td> <code>navigation</code> </td>
* </tr>
* <tr>
* <td> <code>::url::</code> </td>
* <td> URL stub of the current applications name tree</td>
* <td> <code>admin</code> </td>
* <td> <code>::url::</code> </td>
* <td> URL stub of the current applications name tree</td>
* <td> <code>admin</code> </td>
* </tr>
* <tr>
* <td> <code>::prefix::</code> </td>
* <td> ??</td>
* <td> <code>??</code> </td>
* <td> <code>::prefix::</code> </td>
* <td> ??</td>
* <td> <code>??</code> </td>
* </tr>
* <tr>
* <td> <code>::outputtype::</code> </td>
* <td> Output format. </td>
* <td> <code>text_html</code> </td>
* <td> <code>::outputtype::</code> </td>
* <td> Output format. </td>
* <td> <code>text_html</code> </td>
* </tr>
* <tr>
* <td> <code>::locale::</code> </td>
* <td> Current locale </td>
* <td> <code>fr_FR</code> </td>
* <td> <code>::locale::</code> </td>
* <td> Current locale </td>
* <td> <code>fr_FR</code> </td>
* </tr>
* <tr>clear
*
* <td> <code>::outputtype::</code> </td>
* <td> Output format. </td>
* <td> <code>text_html</code> </td>
* <tr>clear
*
* <td> <code>::outputtype::</code> </td>
* <td> Output format. </td>
* <td> <code>text_html</code> </td>
* </tr>
* </table>
*
@ -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.
* </p>
*
* 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 <code>key</code>
* @param gen a pattern generator for producing values to be substituted for
* <code>key</code>
*/
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);
}
}

View File

@ -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 <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() {
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 <code>URL</code> to the top-level template resource
*
* @return an <code>XSLTemplate</code> instance representing
* <code>source</code>
* <code>source</code>
*/
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 <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
* 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 <code>XSLTemplate</code> instance representing
* <code>source</code>
* <code>source</code>
*/
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 <code>XSLTemplate</code> 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 <code>XSLTemplate</code> 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 <code>java.net.URL</code> 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);
}
}

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
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<StylesheetResolver> clazz
= (Class<StylesheetResolver>) 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
* <code>com.arsdigita.templating.stylesheet_resolver</code>
* 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);
}
}

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>
* 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>
* 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.LoginSignal
* @see com.arsdigita.web.ReturnSignal
* @see com.arsdigita.web.WebConfig
* @see com.arsdigita.web.LegacyWebConfig
* @see com.arsdigita.web.Application
* @author Justin Ross
* &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
*/
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();

View File

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

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
* 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 &lt;jross@redhat.com&gt;
* @author <a href="jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
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 <code>CMSConfig</code> 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<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);
}
// /////////////////////////////////////////////////////////////////////////
// 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<ConstraintViolation<WebConfig>> 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<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;
}
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<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,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 &lt;rhs@mit.edu&gt;
* @version $Id: WorkflowConfig.java 287 2005-02-22 00:29:02Z sskracic $
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
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 <code>ContentSectionConfig</code> 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);
}
}

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");
}
}