Skip to content

Commit

Permalink
Allow override core operators (#456)
Browse files Browse the repository at this point in the history
  • Loading branch information
cnogueira authored and ebussieres committed Aug 8, 2019
1 parent e16d5e3 commit 2a6bd4c
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 82 deletions.
56 changes: 41 additions & 15 deletions pebble/src/main/java/com/mitchellbosecke/pebble/PebbleEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,8 @@ public class PebbleEngine {
* Constructor for the Pebble Engine given an instantiated Loader. This method does only load
* those userProvidedExtensions listed here.
*
* @param loader The template loader for this engine
* @param syntax the syntax to use for parsing the templates.
* @param extensions The userProvidedExtensions which should be loaded.
* @param loader The template loader for this engine
* @param syntax the syntax to use for parsing the templates.
*/
private PebbleEngine(Loader<?> loader,
Syntax syntax,
Expand All @@ -90,7 +89,7 @@ private PebbleEngine(Loader<?> loader,
PebbleCache<CacheKey, Object> tagCache,
PebbleCache<Object, PebbleTemplate> templateCache,
ExecutorService executorService,
Collection<? extends Extension> extensions,
ExtensionRegistry extensionRegistry,
ParserOptions parserOptions,
EvaluationOptions evaluationOptions) {

Expand All @@ -101,7 +100,7 @@ private PebbleEngine(Loader<?> loader,
this.tagCache = tagCache;
this.executorService = executorService;
this.templateCache = templateCache;
this.extensionRegistry = new ExtensionRegistry(extensions);
this.extensionRegistry = extensionRegistry;
this.parserOptions = parserOptions;
this.evaluationOptions = evaluationOptions;
}
Expand Down Expand Up @@ -283,6 +282,8 @@ public static class Builder {

private boolean greedyMatchMethod = false;

private boolean allowOverrideCoreOperators = false;

/**
* Creates the builder.
*/
Expand Down Expand Up @@ -422,6 +423,17 @@ public Builder autoEscaping(boolean autoEscaping) {
return this;
}

/**
* Sets whether or not core operators overrides should be allowed.
*
* @param allowOverrideCoreOperators Whether or not core operators overrides should be allowed.
* @return This builder object
*/
public Builder allowOverrideCoreOperators(boolean allowOverrideCoreOperators) {
this.allowOverrideCoreOperators = allowOverrideCoreOperators;
return this;
}

/**
* Sets the default escaping strategy of the built-in escaper extension.
*
Expand All @@ -436,7 +448,7 @@ public Builder defaultEscapingStrategy(String strategy) {
/**
* Adds an escaping strategy to the built-in escaper extension.
*
* @param name The name of the escaping strategy
* @param name The name of the escaping strategy
* @param strategy The strategy implementation
* @return This builder object
*/
Expand Down Expand Up @@ -472,7 +484,7 @@ public Builder allowGetClass(boolean allowGetClass) {
* Enable/disable treat literal decimal as Integer. Default is disabled, treated as Long.
*
* @param literalDecimalTreatedAsInteger toggle to enable/disable literal decimal treated as
* integer
* integer
* @return This builder object
*/
public Builder literalDecimalTreatedAsInteger(boolean literalDecimalTreatedAsInteger) {
Expand Down Expand Up @@ -513,13 +525,7 @@ public Builder greedyMatchMethod(boolean greedyMatchMethod) {
*/
public PebbleEngine build() {

// core extensions
List<Extension> extensions = new ArrayList<>();
extensions.add(new CoreExtension());
extensions.add(this.escaperExtension);
extensions.add(new I18nExtension());
extensions.addAll(this.userProvidedExtensions);
extensions.add(new AttributeResolverExtension());
ExtensionRegistry extensionRegistry = buildExtensionRegistry();

// default loader
if (this.loader == null) {
Expand Down Expand Up @@ -562,7 +568,27 @@ public PebbleEngine build() {

return new PebbleEngine(this.loader, this.syntax, this.strictVariables, this.defaultLocale,
this.tagCache, this.templateCache,
this.executorService, extensions, parserOptions, evaluationOptions);
this.executorService, extensionRegistry, parserOptions, evaluationOptions);
}

private ExtensionRegistry buildExtensionRegistry() {
ExtensionRegistry extensionRegistry = new ExtensionRegistry();

extensionRegistry.addExtension(new CoreExtension());
extensionRegistry.addExtension(this.escaperExtension);
extensionRegistry.addExtension(new I18nExtension());

for (Extension userProvidedExtension : this.userProvidedExtensions) {
if (allowOverrideCoreOperators) {
extensionRegistry.addOperatorOverridingExtension(userProvidedExtension);
} else {
extensionRegistry.addExtension(userProvidedExtension);
}
}

extensionRegistry.addExtension(new AttributeResolverExtension());

return extensionRegistry;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,74 +59,91 @@ public class ExtensionRegistry {

private final List<AttributeResolver> attributeResolver = new ArrayList<>();

public ExtensionRegistry() {
}

public ExtensionRegistry(Collection<? extends Extension> extensions) {

for (Extension extension : extensions) {
// token parsers
List<TokenParser> tokenParsers = extension.getTokenParsers();
if (tokenParsers != null) {
for (TokenParser tokenParser : tokenParsers) {
this.tokenParsers.put(tokenParser.getTag(), tokenParser);
}
addExtension(extension);
}
}

public void addOperatorOverridingExtension(Extension extension) {
addExtension(extension, true);
}

public void addExtension(Extension extension) {
addExtension(extension, false);
}

private void addExtension(Extension extension, boolean operatorOverriding) {
// token parsers
List<TokenParser> tokenParsers = extension.getTokenParsers();
if (tokenParsers != null) {
for (TokenParser tokenParser : tokenParsers) {
this.tokenParsers.put(tokenParser.getTag(), tokenParser);
}
}

// binary operators
List<BinaryOperator> binaryOperators = extension.getBinaryOperators();
if (binaryOperators != null) {
for (BinaryOperator operator : binaryOperators) {
if (!this.binaryOperators
.containsKey(operator.getSymbol())) { // disallow overriding core operators
this.binaryOperators.put(operator.getSymbol(), operator);
}
// binary operators
List<BinaryOperator> binaryOperators = extension.getBinaryOperators();
if (binaryOperators != null) {
for (BinaryOperator operator : binaryOperators) {
if (operatorOverriding) {
this.binaryOperators.put(operator.getSymbol(), operator);
} else {
this.binaryOperators.putIfAbsent(operator.getSymbol(), operator);
}
}
}

// unary operators
List<UnaryOperator> unaryOperators = extension.getUnaryOperators();
if (unaryOperators != null) {
for (UnaryOperator operator : unaryOperators) {
if (!this.unaryOperators
.containsKey(operator.getSymbol())) { // disallow override core operators
this.unaryOperators.put(operator.getSymbol(), operator);
}
// unary operators
List<UnaryOperator> unaryOperators = extension.getUnaryOperators();
if (unaryOperators != null) {
for (UnaryOperator operator : unaryOperators) {
if (operatorOverriding) {
this.unaryOperators.put(operator.getSymbol(), operator);
} else {
this.unaryOperators.putIfAbsent(operator.getSymbol(), operator);
}
}
}

// filters
Map<String, Filter> filters = extension.getFilters();
if (filters != null) {
this.filters.putAll(filters);
}
// filters
Map<String, Filter> filters = extension.getFilters();
if (filters != null) {
this.filters.putAll(filters);
}

// tests
Map<String, Test> tests = extension.getTests();
if (tests != null) {
this.tests.putAll(tests);
}
// tests
Map<String, Test> tests = extension.getTests();
if (tests != null) {
this.tests.putAll(tests);
}

// tests
Map<String, Function> functions = extension.getFunctions();
if (functions != null) {
this.functions.putAll(functions);
}
// functions
Map<String, Function> functions = extension.getFunctions();
if (functions != null) {
this.functions.putAll(functions);
}

// global variables
Map<String, Object> globalVariables = extension.getGlobalVariables();
if (globalVariables != null) {
this.globalVariables.putAll(globalVariables);
}
// global variables
Map<String, Object> globalVariables = extension.getGlobalVariables();
if (globalVariables != null) {
this.globalVariables.putAll(globalVariables);
}

// node visitors
List<NodeVisitorFactory> nodeVisitors = extension.getNodeVisitors();
if (nodeVisitors != null) {
this.nodeVisitors.addAll(nodeVisitors);
}
// node visitors
List<NodeVisitorFactory> nodeVisitors = extension.getNodeVisitors();
if (nodeVisitors != null) {
this.nodeVisitors.addAll(nodeVisitors);
}

// attribute resolver
List<AttributeResolver> attributeResolvers = extension.getAttributeResolver();
if (attributeResolvers != null) {
this.attributeResolver.addAll(attributeResolvers);
}
// attribute resolver
List<AttributeResolver> attributeResolvers = extension.getAttributeResolver();
if (attributeResolvers != null) {
this.attributeResolver.addAll(attributeResolvers);
}
}

Expand Down
Loading

0 comments on commit 2a6bd4c

Please sign in to comment.