Magnolia 6.0 reached end of life on June 26, 2019. This branch is no longer supported, see End-of-life policy.
Voters are used in Magnolia whenever configuration values are not assigned at startup but instead depend on rules. The rules are user-defined using voter classes which evaluate established criteria by determining true or false of each rule.
Voters are currently used for:
The rules to determine values should be configurable and discrete.
For example, the Cache module has to determine if a requested resource may be cached or not. There may be a series of voters that feel responsible for casting a vote on that decision. The winner of a "voting round" is based on the concept of highest according to absolute value.
Voters are classes which calculate an int
vote value, where positive (1, 2, 3, ...) results are treated as "yes" or "true" and (0, -1, -2, ...) results are treated as "no" or "false". If you have a set of voters, then the result of a voting is the largest absolute result. If there are two voters with the same absolute result, then the one with the higher positive value will be taken.
Examples of voting decisions:
Set | Vote | Outcome Description |
---|---|---|
-3, 0, 2 | -3 | The result of this voting round is a strong negative vote. Since the absolute value of 3 is greater than 2, then the negative, or false vote, is casted. |
-3, 0, 3 | 3 | In this case, the absolute value for the negative side and positive side have the same weight so the end result is to cast a positive, or true, vote. The default is to lean positive in the case of a tie vote. |
-3, 0, 4 | 4 | The result of this voting round is a strong positive vote. A vote of true is casted. |
The way voters are configured can vary based on the use case. One common use case for voters is as part of a filter configuration. Since filters can be costly to execute you can save precious execution time by configuring a bypass to be checked prior to running the filter. Any filter which extends AbstractMgnlFilter can have a set of Voter bypasses configured. Each bypass is checked in the same order in which they are defined, top-down.
In the above example we see three bypasses configured on the registration filter. In this case the filter uses the URIPatternVoter for each bypass. We want the system to allow these resource requests to bypass this filter as it does not apply for the registration process. The resources are for the registration form itself.
Most of Magnolia's voter classes can be found in the core module in the package
info.magnolia.voting.votes
. Using one or more of these voters you can create simple or complex configurations which change the behavior of the product.
Voting arrays can also be nested creating complex decision trees.
All voter classes should implement the Voter
interface. The Voting
interface provides a bases for working with multiple voters. Some classes extend from abstract base classes which provide default configuration for other voter classes.
interface: info.magnolia.voting.voters.Voter
All voter classes by implement the Voter interface.
The individual votes can then be operated on using Boolean logic. The Voter interface requires that you implement a vote()
method which takes in the object T and return int. These boolean voters return "1" for a "true" and "0" for a "false" result.
interface: info.magnolia.voting.Voting
The Voting interface is for dealing with sets of voters. Options are AND, OR, HIGHEST_LEVEL voting.
Some voter classes extend from abstract base classes which provide default configurations.
abstract class: info.magnolia.voting.voters.BaseVoterImpl
implements Voter
BaseVoterImpl is the abstract voter that all other voters should extend from. It provides common properties for most other voters.
Properties:
name | optional Either the node name itself or the value of this property. |
enabled | optional Enable or disable the any property which extends this class. |
abstract class: info.magnolia.voting.voters.AbstractBoolVoter
extends BaseVoterImpl
AbstractBoolVoter is used to create boolean voters which can't return integer values. You can steer the returned values by setting the trueValue and falseValue. Classes extending this class should override the boolVote()
method.
Properties:
falseValue | optional , defaults to 0 What is the value that should be returned for a false vote. |
trueValue | optional , defaults to 1 What is the value that should be returned for a false vote. |
not | optional Negate the final result of the if (not) outcome = -outcome; |
level | optional The weight of the vote in terms of |
abstract class: info.magnolia.voting.voters.BasePatterVoter
extends AbstractBoolVoter
BasePatternVoter uses URLs to match against the pattern. The returned vote is the length of the pattern. This allows oversteering less precise votes (like allow /something/* but deny /somthing/otherthing/*). You can use the inverse property which will then return the negative value on a match. This is not the same thing as using the not property which will then vote if the pattern does not match at all.
BasePatternVoter implementations are typed to <Object> because they can work with String value, but will otherwise use the ThreadLocal context and its AggregationState. Finally, it will use a given HttpServletRequest value.
Properties:
pattern | required The pattern to be matched with the current URI. |
inverse | optional Returns the negative value of the length of the pattern |
abstract class: info.magnolia.voting.voters.AbstractRequestHeaderPatternVoter
extends AbstractBoolVoter
AbstractRequestHeaderPatternVoter is used to match the request headers against a pattern.
Properties:
headerName | required The name of the header to be matched. |
These classes are provided in the core module and can be used out of the box. Most voters extend from BaseVoterImpl
either directly or indirectly. When dealing with a set of voters then it's typical to implement the Voting
interface.
class: info.magnolia.voting.voters.AndVoting
implements Voting
AndVoting returns the maximum vote, but only if all voters voted positive.
class: info.magnolia.voting.voters.AuthenticatedVoter
extends AbstractBoolVoter
AuthenticatedVoter checks if the current user is authenticated. Does not vote on the passed object.
class: info.magnolia.voting.voters.BoolVoterSet
extends AbstractBoolVoter
BoolVoterSet combines a set of other voters based on a given logical operation. It's backed by VoterSet, but boolean-aware. In particular, this means that the "not" flag is handled correctly.
class: info.magnolia.voting.DefaultVoting
implements Voting
This voter has DEBUG capabilities. Use the Log Tools app to turn on debugging.
DefaultVoting returns the highest vote in the set of voters. The voting can return 0 if no voter casts a meaningful vote.
class: info.magnolia.voting.voters.DomainNameRegexVoter
extends AbstractBoolVoter
DomainNameRegexVoter determines if the request has domain that matches configured regex. Typed to Object, as it can vote on both a passed HttpServletRequest
, or the current context (i.e. WebContext
) if any.
Properties:
domain | required A regular expression to match the requested domain against. |
class: info.magnolia.voting.voters.ExtensionVoter
extends AbstractBoolVoter
Typed to Object
, as it can vote on a passed String. If a String is not passed then it votes on the extension found in the AggregationState
.
ExtensionVoter returns:
false
if the extension is not a valid mimetype (as configured in config:/server/MIMEMapping).false
if the allow list exists, but the extension is not in the allow list.false
if the deny list exists and the extension is in the deny list.true
otherwiseProperties:
allow | optional A comma separated lists of allowed extensions. |
deny | optional A comma separated lists of denied extensions. |
class: info.magnolia.voting.voters.FalseVoter
extends AbstractBoolVoter
FalseVoter simply returns false
.
class: info.magnolia.voting.voters.ForwardVoter
extends AbstractBoolVoter
ForwardVoter returns true
if the request has been forwarded. It works by checking to see if the FORWARD_REQUEST_URI attribute is not null.
class: info.magnolia.voting.voters.IfVoter
This voter has DEBUG capabilities. Use the Log Tools app to turn on debugging.
Conditional voter. If the "condition" voter is positive, returns the "then" voter's value, otherwise returns the "otherwise" voter's value.
Properties:
condition | required The Voter configuration to base the initial decision path. |
then | required The Voter configuration to be used if condition is |
otherwise | required The Voter configuration to be used if condition is |
class: info.magnolia.voting.voters.InverseVoter
InverseVoter is a voter wrapper. It calls the vote() method of the wrapped voter and multiplies the value by -1 (i.e. 5 * -1 --> -5)
Properties:
voter | required The Voter configuration to be inverted. |
class: info.magnolia.voting.voters.NotVoter
extends AbstractBoolVoter
NotVoter inverts the boolean outcome of a voter. This is not the same thing as inverting the value InverseVoter.
Properties:
voter | required The Voter configuration to be notted. |
class: info.magnolia.voting.voters.NullVoter
implements Voter
NullVoter always returns 0 and is disabled by default. Useful for default values.
Properties:
enabled | optional , defaults to false Enable or disable the any property which extends this class. |
class: info.magnolia.voting.voters.OnAdminVoter
extends AbstractBoolVoter
OnAdminVoter checks if the admin
property of the server configuration is true
or false
.
class: info.magnolia.voting.voters.OrVoting
implements Voting
OrVoting returns the first positive vote. Negative votes are ignored.
class: info.magnolia.voting.voters.PropertyVoter
extends AbstractBoolVoter
PropertyVoter checks if the named Magnolia property has the expected value.
Properties:
property | required Configuration property set in the magnolia properties file. |
value | required Expected value to return a "1" or "true" vote. |
class: info.magnolia.voting.voters.RequestExtensionVoter
extends AbstractBoolVoter
RequestExtensionVoter checks the extension set in the AggregationState
object against a list of allowed and/or rejected extensions.
This voter is very similar to the ExtensionVoter
with two exceptions. They are configured differently and RequestExtensionVoter
can only vote against the AggregationState
object. Meaning, that you cannot pass any objects to RequestExtensionVoter
.
Properties:
allowed | optional A List object of allowed extensions. |
rejected | optional A List object of rejected extensions. |
class: info.magnolia.voting.voters.RequestHasParametersVoter
extends AbstractBoolVoter
RequestHasParametersVoter checks if the request used the "POST" method or if there are request parameters. Typed to Object, as it can vote on both a passed HttpServletRequest
, or the current context (i.e. WebContext
) if any.
class: info.magnolia.voting.voters.RequestHeaderRegexVoter
extends AbstractRequestHeaderPatternVoter
RequestHeaderPatternRegexVoter takes a plain regex pattern which is matched against the specified request (configured in the headerName
property).
Properties:
pattern | required A regular expression to match the header against. |
class: info.magnolia.voting.voters.RequestHeaderPatternSimpleVoter
extends AbstractRequestHeaderPatternVoter
RequestHeaderPatternSimpleVoter checks if the specified request header matches a simple url pattern (SimpleUrlPattern).
class: info.magnolia.voting.voters.RequestParameterVoter
extends AbstractBoolVoter
RequestHeaderPatternSimpleVoter checks for a specific GET and POST parameter and an optional value. If no value is specified the voter just checks for the existence of the parameter no matter what value is set.
Properties:
| required The name of the parameter to be checked. |
parameterValue | optional The expected value of the parameter for a true vote. |
class: info.magnolia.voting.voters.RoleBaseVoter
extends AbstractBoolVoter
RoleBaseVoter checks if the current user has access permissions by comparing user roles and configured roles. The configured roles can be allowed or denied.
| required A list or roles to compare against. |
class: info.magnolia.voting.voters.SystemOrAdminUserVoter
extends AbstractBoolVoter
SystemOrAdminUserVoter checks if the current user is a system or admin user by checking the user's Realm.
class: info.magnolia.voting.voters.TrueVoter
extends AbstractBoolVoter
TrueVoter extends AbstractBoolVoter
which simply returns true
.
class: info.magnolia.voting.voters.URIPatternVoter
extends BasePatternVoter
URIPatternVoter checks if URI matches the pattern.
class: info.magnolia.voting.voters.URIRegexVoter
extends BasePatternVoter
URIRegexVoter extends BasePatternVoter
and uses the pattern to match against the current URI in the AggregationState
.
class: info.magnolia.voting.voters.URIStartsWithVoter
extends BasePatternVoter
URIStartsWithVoter extends BasePatternVoter
and checks if the URI starts with the given pattern.
class: info.magnolia.voting.voters.UserAgentVoter
extends AbstractBoolVoter
UserAgentVoter extends AbstractBoolVoter
and checks the user agent header in request object against a list of allowed and/or rejected user agents. Typed to Object, as it can vote on both a passed HttpServletRequest, or the current context, if any. Checks if the URI starts with the given pattern.
Properties:
allowed | optional A sub-configuration which holds a list of String properties for whitelisting user agents. The names of the child properties is arbitrary. |
rejected | optional A sub-configuration which holds a list of String properties for blacklisting user agents. The names of the child properties is arbitrary. |
class: info.magnolia.voting.voters.VoterSet
extends BaseVoterImpl
VoterSet implements the Voting
interface and takes a set of voters. The voting can be set as well as the returned level. If the level is not set (0) the votings result is returned.
Properties:
level | optional The level corresponds to the "weight" or "importance" of the vote. Some votes might carry more weight in the voting process. |
op | optional Operation to be performed. Options are AND, OR, HIGHEST_LEVEL voting. |
not |