You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by an...@apache.org on 2019/07/30 16:17:11 UTC
[sling-org-apache-sling-resourceresolver] 02/02: Migrated the Sling
Interplation to Lang3 StrSubtitutor,
adjusted the tests and fixed some merge problems
This is an automated email from the ASF dual-hosted git repository.
andysch pushed a commit to branch feature/SLING-7768
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourceresolver.git
commit bdc07c81a082329627a8bb2ba14e0b1fde41531e
Author: Andreas Schaefer <sc...@iMac.local>
AuthorDate: Tue Jul 30 09:16:55 2019 -0700
Migrated the Sling Interplation to Lang3 StrSubtitutor, adjusted the tests and fixed some merge problems
---
README.md | 54 ++++++++
.../resourceresolver/impl/mapping/MapEntries.java | 56 +-------
.../impl/mapping/StringInterpolationProvider.java | 68 +---------
.../StringInterpolationProviderConfiguration.java | 24 ++++
.../mapping/StringInterpolationProviderImpl.java | 114 ++++------------
.../impl/EtcMappingResourceResolverTest.java | 33 +----
.../mapping/AbstractMappingMapEntriesTest.java | 27 +---
.../impl/mapping/EtcMappingMapEntriesTest.java | 13 --
.../impl/mapping/MapEntriesTest.java | 20 +--
.../impl/mapping/ResourceMapperImplTest.java | 3 +-
.../mapping/StringInterpolationMapEntriesTest.java | 4 +-
.../StringInterpolationProviderImplTest.java | 148 +++++++++++++++------
.../sling/resourceresolver/util/MockTestUtil.java | 87 ++++--------
13 files changed, 262 insertions(+), 389 deletions(-)
diff --git a/README.md b/README.md
index 02bf7bc..00d8c1c 100644
--- a/README.md
+++ b/README.md
@@ -7,3 +7,57 @@
This module is part of the [Apache Sling](https://sling.apache.org) project.
This bundle provides the Resource Resolver and Resource Resolver Factory
+
+## ETC Map String Interpolation
+
+Setting up ETC Mappings (/etc/map) for different instances like dev, stage,
+qa and production was time consuming and error prone due to copy-n-paste
+errors.
+As a new feature Sling now supports String Interpolation in the /etc/map.
+With it it is possible to create a single set of etc-mapping and then adjust
+the actual values of an instance by an OSGi configuration.
+By default a variable name is enclosed in **${}** with a **$** as escape
+character and no in-variable-substitution. All of that is configurable
+together with the actual value map.
+
+### Setup
+
+The Substitution Configuration can be found in the OSGi Configuration
+as **Apache Sling String Interpolation Provider**. The property **Placeholder
+Values** takes a list of **key=value** entries where each of them map a
+variable with its actual value.
+In our little introduction we add an entry of
+**phv.default.host.name=localhost**. Save the configuration for now.
+Before going on make sure that you know Mapping Location configuration
+in the OSGi configuration of **Apache Sling Resource Resolver Factory**.
+Now to to **composum** and go to that node. If it does not exist then create
+one. The mapping should look like this:
+* etc
+ * map
+ * http
+ * ${phv.fq.host.name}.8080
+
+Opening the page **http://localhost:8080/starter/index.html** should
+work just fine.
+
+### Testing
+
+Now got back to the String Interpolation configuration and change the value
+to **qa.author.acme.com** and save it.
+
+For local testing open your **hosts** file (/etc/hosts on Unix) and add a
+line like this:
+```
+127.0.0.1 qa.author.acme.com
+```
+save it and test with `ping qa.author.acme.com` to make sure the name
+resolves.
+Now you should be able to open the same page with:
+**http://qa.author.acme.com/starter/index.html**.
+
+Now do the same with **phv.fq.host.name=staging.author.acme.com**.
+
+The String Interpolation works with any part of the etc-map tree.
+
+
+
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
index 2efa826..b13b25a 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
@@ -163,7 +163,8 @@ public class MapEntries implements
this.resolveMapsMap = Collections.singletonMap(GLOBAL_LIST_KEY, (List<MapEntry>)Collections.EMPTY_LIST);
this.mapMaps = Collections.<MapEntry> emptyList();
this.vanityTargets = Collections.<String,List <String>>emptyMap();
- this.aliasMap = Collections.emptyMap();
+ this.aliasMap = Collections.<String, Map<String, String>>emptyMap();
+ this.stringInterpolationProvider = stringInterpolationProvider;
doInit();
@@ -355,7 +356,6 @@ public class MapEntries implements
* Remove all aliases for the content path
* @param contentPath The content path
* @param path Optional sub path of the vanity path
- * @param refreshed Flag if session needs refresh
* @return {@code true} if a change happened
*/
private boolean removeAlias(final String contentPath, final String path, final AtomicBoolean resolverRefreshed) {
@@ -713,7 +713,7 @@ public class MapEntries implements
/**
* Handles the change to any of the node properties relevant for vanity URL
- * mappings. The {@link #MapEntries(ResourceResolverFactoryImpl, BundleContext, EventAdmin)}
+ * mappings. The {@link #MapEntries(MapConfigurationProvider, BundleContext, EventAdmin, StringInterpolationProvider)}
* constructor makes sure the event listener is registered to only get
* appropriate events.
*/
@@ -968,10 +968,7 @@ public class MapEntries implements
trailingSlash = true;
}
// Check for placeholders and replace if needed
- StringInterpolationProvider.Check check = stringInterpolationProvider.hasPlaceholder(name);
- if(check.getStatus() == StringInterpolationProvider.STATUS.found) {
- name = stringInterpolationProvider.resolve(check);
- }
+ name = stringInterpolationProvider.substitute(name);
final String childPath = parentPath.concat(name);
@@ -1043,58 +1040,15 @@ public class MapEntries implements
*/
private Map<String, Map<String, String>> loadAliases(final ResourceResolver resolver) {
final Map<String, Map<String, String>> map = new ConcurrentHashMap<>();
- String queryString = this.factory.isForceNoAliasTraversal() ? ALIAS_QUERY_NO_TRAVERSAL : ALIAS_QUERY_DEFAULT;
- while (true){
- try {
+ final String queryString = "SELECT sling:alias FROM nt:base WHERE sling:alias IS NOT NULL";
final Iterator<Resource> i = resolver.findResources(queryString, "sql");
while (i.hasNext()) {
final Resource resource = i.next();
loadAlias(resource, map);
}
- break;
- } catch (SlingException e) {
- Throwable cause = unwrapThrowable(e);
- if (cause instanceof IllegalArgumentException && ALIAS_QUERY_NO_TRAVERSAL.equals(queryString)) {
- log.debug(
- "Expected index not available yet - will retry", e);
- try {
- TimeUnit.MILLISECONDS.sleep(getTraversalRetryInterval());
- } catch (InterruptedException ex) {
- log.warn("Interrupted while sleeping", ex);
- }
- } else if (cause instanceof ParseException) {
- if (ALIAS_QUERY_NO_TRAVERSAL.equals(queryString)) {
- log.warn("Traversal fail option set but query not accepted by queryengine, falling back to allowing traversal as queryengine might not support option", e);
- queryString = ALIAS_QUERY_DEFAULT;
- } else {
- log.error("Queryengine couldn't parse query - interrupting loading of aliasmap",e);
- break;
- }
- try {
- TimeUnit.MILLISECONDS.sleep(getTraversalRetryInterval());
- } catch (InterruptedException ex) {
- log.warn("Interrupted while sleeping", ex);
- }
-
-
- } else {
- log.error("QueryEngine not able to process query {} ", queryString, e);
- break;
- }
- }
- }
return map;
}
- /**
- * Extract root cause of exception
- * @param e {@code Throwable} to be checked
- * @return Root {@code Throwable}
- */
- private Throwable unwrapThrowable(Throwable e) {
- return e.getCause() == null ? e : unwrapThrowable(e.getCause());
- }
-
/**
* Load alias given a resource
*/
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProvider.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProvider.java
index aa398e2..eabf1d2 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProvider.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProvider.java
@@ -31,70 +31,16 @@ import java.util.List;
*/
public interface StringInterpolationProvider {
- enum STATUS {found, unknown, none};
-
- public static final String PLACEHOLDER_START_TOKEN = "${";
- public static final String PLACEHOLDER_END_TOKEN = "}";
- /**
- * Checks if the given values contains a placeholder and if that placeholder is known
- * @param value String to check
- * @return Indicator if the given strings contains a known, unknown or no placeholders
- */
- Check hasPlaceholder(String value);
+ String DEFAULT_PREFIX = "${";
+ String DEFAULT_SUFFIX = "}";
+ char DEFAULT_ESCAPE_CHARACTER = '$';
+ boolean DEFAULT_IN_VARIABLE_SUBSTITUTION = false;
/**
* Replaces any placeholders with the replacement value
- * ATTENTION: it is assumed that the string was checked and STATUS.found was returned.
- * Any known placeholders will be replaced with an empty string
*
- * @param check Instance returned by has placeholder method
- * @return Resolve string
+ * @param text Text to be substituted
+ * @return Substituted string
*/
- String resolve(Check check);
-
- public class Check {
- private STATUS status;
- private List<PlaceholderContext> placeholderContextList;
- private String line;
-
- public Check(STATUS status, String line, List<PlaceholderContext> placeholderContextList) {
- this.status = status;
- this.line = line;
- this.placeholderContextList = placeholderContextList;
- }
-
- public STATUS getStatus() { return status; }
-
- public List<PlaceholderContext> getPlaceholderContextList() {
- return placeholderContextList;
- }
-
- public String getLine() {
- return line;
- }
- }
-
- public class PlaceholderContext {
- private int start;
- private int end;
- private String name;
-
- public PlaceholderContext(int start, int end, String name) {
- this.start = start;
- this.end = end;
- this.name = name;
- }
-
- public int getStart() {
- return start;
- }
-
- public int getEnd() {
- return end;
- }
-
- public String getName() {
- return name;
- }
- }
+ String substitute(String text);
}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProviderConfiguration.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProviderConfiguration.java
index 664669e..8b5f371 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProviderConfiguration.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProviderConfiguration.java
@@ -21,9 +21,33 @@ package org.apache.sling.resourceresolver.impl.mapping;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import static org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider.DEFAULT_ESCAPE_CHARACTER;
+import static org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider.DEFAULT_IN_VARIABLE_SUBSTITUTION;
+import static org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider.DEFAULT_PREFIX;
+import static org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider.DEFAULT_SUFFIX;
+
@ObjectClassDefinition(name = "Apache Sling String Interpolation Provider",
description = "Configures the String Interpolation Provider and the location of its key/value pairs")
public @interface StringInterpolationProviderConfiguration {
+
+ // Setup for the String Substitution
+ @AttributeDefinition(
+ name = "Substitution Prefix",
+ description = "The Prefix of the Variable to be replaced (default = '${')")
+ String substitution_prefix() default DEFAULT_PREFIX;
+ @AttributeDefinition(
+ name = "Substitution Suffix",
+ description = "The Suffix of the Variable to be replaced (deault = '}'")
+ String substitution_suffix() default DEFAULT_SUFFIX;
+ @AttributeDefinition(
+ name = "Substitution Escape Character",
+ description = "The Escape Character for Prefix or Suffix (default = '$'")
+ char substitution_escape_character() default DEFAULT_ESCAPE_CHARACTER;
+ @AttributeDefinition(
+ name = "Enable Substitution in Variables",
+ description = "Flag that indicates if substitution is allowed in Variables (default = false")
+ boolean substitution_in_variables() default DEFAULT_IN_VARIABLE_SUBSTITUTION;
+
@AttributeDefinition(
name = "Placeholder Values",
description = "A list of key / value pairs separated by a equal (=) sign. " +
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProviderImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProviderImpl.java
index 5150c83..f5bfab9 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProviderImpl.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProviderImpl.java
@@ -18,7 +18,7 @@
*/
package org.apache.sling.resourceresolver.impl.mapping;
-import org.osgi.framework.BundleContext;
+import org.apache.commons.lang3.text.StrSubstitutor;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
@@ -30,9 +30,7 @@ import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
@Designate(ocd = StringInterpolationProviderConfiguration.class)
@@ -75,9 +73,9 @@ public class StringInterpolationProviderImpl
);
}
- private BundleContext bundleContext;
- private StringInterpolationProviderConfiguration config = DEFAULT_CONFIG;
+// private StringInterpolationProviderConfiguration config = DEFAULT_CONFIG;
private Map<String, String> placeholderEntries = new HashMap<>();
+ private StrSubstitutor substitutor = new StrSubstitutor();
// ---------- SCR Integration ---------------------------------------------
@@ -85,10 +83,14 @@ public class StringInterpolationProviderImpl
* Activates this component (called by SCR before)
*/
@Activate
- protected void activate(final BundleContext bundleContext, final StringInterpolationProviderConfiguration config) {
- this.bundleContext = bundleContext;
- this.config = config;
- for(String line: this.config.place_holder_key_value_pairs()) {
+ protected void activate(final StringInterpolationProviderConfiguration config) {
+ String prefix = config.substitution_prefix();
+ String suffix = config.substitution_suffix();
+ char escapeCharacter = config.substitution_escape_character();
+ boolean substitudeInVariables = config.substitution_in_variables();
+
+ String[] valueMap = config.place_holder_key_value_pairs();
+ for(String line: valueMap) {
// Ignore no or empty lines
if(line == null || line.isEmpty()) { continue; }
// Ignore comments
@@ -104,15 +106,22 @@ public class StringInterpolationProviderImpl
}
placeholderEntries.put(line.substring(0, index), line.substring(index + 1));
}
+
+ substitutor = new StrSubstitutor(
+ placeholderEntries,
+ prefix,
+ suffix,
+ escapeCharacter
+ );
+ substitutor.setEnableSubstitutionInVariables(substitudeInVariables);
}
/**
* Modifies this component (called by SCR to update this component)
*/
@Modified
- protected void modified(final BundleContext bundleContext, final StringInterpolationProviderConfiguration config) {
- this.deactivate();
- this.activate(bundleContext, config);
+ protected void modified(final StringInterpolationProviderConfiguration config) {
+ this.activate(config);
}
/**
@@ -120,86 +129,11 @@ public class StringInterpolationProviderImpl
*/
@Deactivate
protected void deactivate() {
- this.bundleContext = null;
- this.config = DEFAULT_CONFIG;
- }
-
- @Override
- public Check hasPlaceholder(String line) {
- STATUS status = STATUS.none;
- List<PlaceholderContext> placeholderContextList = parseLine(line);
- for(PlaceholderContext placeholderContext: placeholderContextList) {
- String name = placeholderContext.getName();
- if(!placeholderEntries.containsKey(name)) {
- logger.warn("Placeholder: '{}' not found in list of Placeholders: '{}'", name, placeholderEntries);
- status = STATUS.unknown;
- }
- status = status == STATUS.none ? STATUS.found : status;
- }
- return new Check(status, line, placeholderContextList);
+ activate(DEFAULT_CONFIG);
}
@Override
- public String resolve(Check check) {
- if(check.getStatus() == STATUS.unknown) {
- logger.warn("Line: '{}' contains unknown placeholders -> ignored", check.getLine());
- return check.getLine();
- }
- List<PlaceholderContext> placeholderContextList = check.getPlaceholderContextList();
- String line = check.getLine();
- String answer = "";
- if(placeholderContextList.isEmpty()) {
- answer = line;
- } else {
- // The carret is the position in the source line. It is used to copy regular text
- int carret = 0;
- for (PlaceholderContext context : check.getPlaceholderContextList()) {
- int start = context.getStart();
- if(start > carret) {
- // There is text between the current position in the source and the next placeholder
- // so copy this into the target line
- String text = line.substring(carret, start);
- answer += text;
- carret += text.length();
- }
- int end = context.getEnd();
- String name = context.getName();
- String value = placeholderEntries.get(name);
- // Add placeholder value into the target line
- answer += value;
- carret = carret + end - start + PLACEHOLDER_END_TOKEN.length();
- }
- if(carret < line.length()) {
- // There is some text left after the last placeholder so copy this to the target line
- answer += line.substring(carret);
- }
- }
- return answer;
- }
-
- private List<PlaceholderContext> parseLine(String line) {
- List<PlaceholderContext> answer = new ArrayList<>();
- int index = -2;
- if(line != null && !line.isEmpty()) {
- while(true) {
- index = line.indexOf(PLACEHOLDER_START_TOKEN, index + 1);
- if (index < 0) {
- break;
- }
- int index2 = line.indexOf(PLACEHOLDER_END_TOKEN, index);
- if(index2 < 0) {
- logger.warn("Given Line: '{}' contains an unclosed placeholder -> ignored", line);
- continue;
- }
- answer.add(
- new PlaceholderContext(
- index,
- index2,
- line.substring(index + PLACEHOLDER_START_TOKEN.length(), index2)
- )
- );
- }
- }
- return answer;
+ public String substitute(String text) {
+ return substitutor.replace(text);
}
}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/EtcMappingResourceResolverTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/EtcMappingResourceResolverTest.java
index 9ae3f7d..6460ff5 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/EtcMappingResourceResolverTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/EtcMappingResourceResolverTest.java
@@ -23,11 +23,8 @@ import org.apache.sling.api.resource.observation.ResourceChange;
import org.apache.sling.api.resource.path.Path;
import org.apache.sling.resourceresolver.impl.mapping.MapConfigurationProvider;
import org.apache.sling.resourceresolver.impl.mapping.MapEntries;
-<<<<<<< HEAD
import org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProviderConfiguration;
import org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProviderImpl;
-=======
->>>>>>> master
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
@@ -57,11 +54,9 @@ import static org.apache.sling.resourceresolver.util.MockTestUtil.callInaccessib
import static org.apache.sling.resourceresolver.util.MockTestUtil.checkInternalResource;
import static org.apache.sling.resourceresolver.util.MockTestUtil.checkRedirectResource;
import static org.apache.sling.resourceresolver.util.MockTestUtil.createRequestFromUrl;
+import static org.apache.sling.resourceresolver.util.MockTestUtil.createStringInterpolationProviderConfiguration;
import static org.apache.sling.resourceresolver.util.MockTestUtil.setInaccessibleField;
-<<<<<<< HEAD
import static org.apache.sling.resourceresolver.util.MockTestUtil.setupStringInterpolationProvider;
-=======
->>>>>>> master
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
@@ -96,13 +91,9 @@ public class EtcMappingResourceResolverTest {
@Mock
ResourceProvider<?> resourceProvider;
-<<<<<<< HEAD
- @Mock
StringInterpolationProviderConfiguration stringInterpolationProviderConfiguration;
StringInterpolationProviderImpl stringInterpolationProvider = new StringInterpolationProviderImpl();
-=======
->>>>>>> master
MapEntries mapEntries;
File vanityBloomFilterFile;
@@ -131,10 +122,8 @@ public class EtcMappingResourceResolverTest {
setInaccessibleField("resourceProviderTracker", activator, resourceProviderTracker);
setInaccessibleField("resourceAccessSecurityTracker", activator, new ResourceAccessSecurityTracker());
setInaccessibleField("bundleContext", activator, bundleContext);
-<<<<<<< HEAD
+ stringInterpolationProviderConfiguration = createStringInterpolationProviderConfiguration();
setInaccessibleField("stringInterpolationProvider", activator, stringInterpolationProvider);
-=======
->>>>>>> master
setInaccessibleField("mapRoot", activator, "/etc/map");
setInaccessibleField("mapRootPrefix", activator, "/etc/map");
setInaccessibleField("observationPaths", activator, new Path[] {new Path("/")});
@@ -145,11 +134,7 @@ public class EtcMappingResourceResolverTest {
when(bundleContext.getDataFile("vanityBloomFilter.txt")).thenReturn(vanityBloomFilterFile);
when(serviceUserMapper.getServiceUserID(any(Bundle.class),anyString())).thenReturn("mapping");
// Activate method is package private so we use reflection to to call it
-<<<<<<< HEAD
- callInaccessibleMethod("activate", commonFactory, BundleContext.class, bundleContext);
-=======
callInaccessibleMethod("activate", null, commonFactory, BundleContext.class, bundleContext);
->>>>>>> master
final Bundle usingBundle = mock(Bundle.class);
resourceResolverFactory = new ResourceResolverFactoryImpl(commonFactory, usingBundle, null);
resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
@@ -163,8 +148,6 @@ public class EtcMappingResourceResolverTest {
return new ArrayList<>();
}
-<<<<<<< HEAD
-=======
/**
* Changes to the /etc/map in our tests are not taking effect until there is an Change Event issued
*
@@ -174,7 +157,6 @@ public class EtcMappingResourceResolverTest {
* @param path Path to the resource root to be refreshed
* @param isExternal External flag of the ResourceChange event
*/
->>>>>>> master
void refreshMapEntries(String path, boolean isExternal) {
((MapEntries) commonFactory.getMapEntries()).onChange(
asList(
@@ -300,11 +282,10 @@ public class EtcMappingResourceResolverTest {
checkInternalResource(resolvedResource, "/anecdotes/stories");
}
-<<<<<<< HEAD
@Test
public void simple_node_string_interpolation() throws Exception {
buildResource("${siv.one}", http, resourceResolver, resourceProvider,PROP_REDIRECT_EXTERNAL, "/content/simple-node");
- setupStringInterpolationProvider(stringInterpolationProvider, stringInterpolationProviderConfiguration, bundleContext, new String[] {"siv.one=test-simple-node.80"});
+ setupStringInterpolationProvider(stringInterpolationProvider, stringInterpolationProviderConfiguration, new String[] {"siv.one=test-simple-node.80"});
refreshMapEntries("/etc/map", true);
@@ -325,7 +306,7 @@ public class EtcMappingResourceResolverTest {
PROP_REG_EXP, "${siv.one}/",
PROP_REDIRECT_EXTERNAL, "/content/simple-match/"
);
- setupStringInterpolationProvider(stringInterpolationProvider, stringInterpolationProviderConfiguration, bundleContext, new String[] {"siv.one=test-simple-match.80"});
+ setupStringInterpolationProvider(stringInterpolationProvider, stringInterpolationProviderConfiguration, new String[] {"siv.one=test-simple-match.80"});
refreshMapEntries("/etc/map", true);
@@ -335,11 +316,12 @@ public class EtcMappingResourceResolverTest {
HttpServletRequest request = createRequestFromUrl("http://test-simple-match:80/");
Resource resolvedResource = resourceResolver.resolve(request, "/");
checkRedirectResource(resolvedResource, "/content/simple-match/", 302);
-=======
+ }
+
/**
* ATTENTION: this tests showcases an erroneous condition of an endless circular mapping in the /etc/map. When
* this test passes this condition is present. After a fix this test must be adjusted.
- *
+ *
* This confirms an issue with the Etc Mapping where a mapping from a node to a child node (here / to /content)
* ends up in a endless circular mapping.
* The only way to recover from this is to go to the OSGi console and change the /etc/map path in the Resource
@@ -368,6 +350,5 @@ public class EtcMappingResourceResolverTest {
resolvedResource = resourceResolver.resolve(request, "/content/content/test.html");
checkRedirectResource(resolvedResource, "/content/content/content/test.html", 302);
->>>>>>> master
}
}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java
index e7129da..44e04a9 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java
@@ -46,10 +46,8 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
-<<<<<<< HEAD
+import static org.apache.sling.resourceresolver.util.MockTestUtil.createStringInterpolationProviderConfiguration;
import static org.apache.sling.resourceresolver.util.MockTestUtil.setupStringInterpolationProvider;
-=======
->>>>>>> master
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyMap;
@@ -82,13 +80,9 @@ public abstract class AbstractMappingMapEntriesTest {
@Mock
ResourceResolver resourceResolver;
-<<<<<<< HEAD
- @Mock
StringInterpolationProviderConfiguration stringInterpolationProviderConfiguration;
StringInterpolationProviderImpl stringInterpolationProvider = new StringInterpolationProviderImpl();
-=======
->>>>>>> master
MapEntries mapEntries;
File vanityBloomFilterFile;
@@ -112,10 +106,6 @@ public abstract class AbstractMappingMapEntriesTest {
when(resourceResolverFactory.isVanityPathEnabled()).thenReturn(true);
when(resourceResolverFactory.getVanityPathConfig()).thenReturn(configs);
when(resourceResolverFactory.isOptimizeAliasResolutionEnabled()).thenReturn(true);
-<<<<<<< HEAD
- when(resourceResolverFactory.isForceNoAliasTraversal()).thenReturn(true);
-=======
->>>>>>> master
when(resourceResolverFactory.getObservationPaths()).thenReturn(new Path[] {new Path("/")});
when(resourceResolverFactory.getMapRoot()).thenReturn(MapEntries.DEFAULT_MAP_ROOT);
when(resourceResolverFactory.getMaxCachedVanityPathEntries()).thenReturn(-1L);
@@ -126,12 +116,9 @@ public abstract class AbstractMappingMapEntriesTest {
map = setupEtcMapResource("/etc", "map");
http = setupEtcMapResource("http", map);
-<<<<<<< HEAD
- setupStringInterpolationProvider(stringInterpolationProvider, stringInterpolationProviderConfiguration, bundleContext, new String[] {});
+ stringInterpolationProviderConfiguration = createStringInterpolationProviderConfiguration();
+ setupStringInterpolationProvider(stringInterpolationProvider, stringInterpolationProviderConfiguration, new String[] {});
mapEntries = new MapEntries(resourceResolverFactory, bundleContext, eventAdmin, stringInterpolationProvider);
-=======
- mapEntries = new MapEntries(resourceResolverFactory, bundleContext, eventAdmin);
->>>>>>> master
final Field aliasMapField = MapEntries.class.getDeclaredField("aliasMap");
aliasMapField.setAccessible(true);
@@ -204,11 +191,7 @@ public abstract class AbstractMappingMapEntriesTest {
return resource;
}
-<<<<<<< HEAD
- MapEntriesTest.DataFuture createDataFuture(ExecutorService pool, final MapEntries mapEntries) {
-=======
DataFuture createDataFuture(ExecutorService pool, final MapEntries mapEntries) {
->>>>>>> master
Future<Iterator<?>> future = pool.submit(new Callable<Iterator<?>>() {
@Override
@@ -216,11 +199,7 @@ public abstract class AbstractMappingMapEntriesTest {
return mapEntries.getResolveMapsIterator("http/localhost.8080/target/justVanityPath");
}
});
-<<<<<<< HEAD
- return new MapEntriesTest.DataFuture(future);
-=======
return new DataFuture(future);
->>>>>>> master
}
void simulateSomewhatSlowSessionOperation(final Semaphore sessionLock) throws InterruptedException {
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/EtcMappingMapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/EtcMappingMapEntriesTest.java
index bfede24..a98ca6e 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/EtcMappingMapEntriesTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/EtcMappingMapEntriesTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.sling.resourceresolver.impl.mapping;
-<<<<<<< HEAD
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.path.Path;
@@ -51,14 +50,6 @@ import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
-=======
-import static org.apache.sling.resourceresolver.impl.ResourceResolverImpl.PROP_REDIRECT_INTERNAL;
-import static org.apache.sling.resourceresolver.impl.mapping.MapEntries.PROP_REDIRECT_EXTERNAL;
-
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.resourceresolver.util.MockTestUtil.ExpectedEtcMapping;
-import org.junit.Test;
->>>>>>> master
/**
* These tests are for the /etc/map setup of the Map Entries when
@@ -136,7 +127,6 @@ public class EtcMappingMapEntriesTest extends AbstractMappingMapEntriesTest {
.addEtcMapEntry("^http/localhost\\.\\d*/gateway/", true, "http://gbiv.com/")
.addEtcMapEntry("^http/localhost\\.\\d*/(stories)/", true, "/anecdotes/$1/");
expectedEtcMapping.assertEtcMap("Etc Mapping for nested internal mixed mapping", mapEntries.getResolveMaps());
-<<<<<<< HEAD
// Not really an etc-map resource but it is good for now
final Resource test = setupEtcMapResource("/scripts", "test");
@@ -258,7 +248,4 @@ public class EtcMappingMapEntriesTest extends AbstractMappingMapEntriesTest {
// Resource mappedResource = resResolver.resolve(request, "/b.html");
// String path = mappedResource.getPath();
// }
-=======
- }
->>>>>>> master
}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
index db072c3..fc6691c 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
@@ -21,11 +21,9 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -33,11 +31,9 @@ import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
@@ -45,22 +41,16 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-import org.apache.sling.api.SlingException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.resource.observation.ResourceChange;
import org.apache.sling.api.resource.observation.ResourceChange.ChangeType;
import org.apache.sling.api.resource.path.Path;
@@ -70,7 +60,6 @@ import org.apache.sling.resourceresolver.impl.mapping.MapConfigurationProvider.V
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@@ -80,7 +69,7 @@ import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.service.event.EventAdmin;
-public class MapEntriesTest {
+public class MapEntriesTest extends AbstractMappingMapEntriesTest {
private MapEntries mapEntries;
@@ -129,7 +118,6 @@ public class MapEntriesTest {
when(resourceResolverFactory.isVanityPathEnabled()).thenReturn(true);
when(resourceResolverFactory.getVanityPathConfig()).thenReturn(configs);
when(resourceResolverFactory.isOptimizeAliasResolutionEnabled()).thenReturn(true);
- when(resourceResolverFactory.isForceNoAliasTraversal()).thenReturn(true);
when(resourceResolverFactory.getObservationPaths()).thenReturn(new Path[] {new Path("/")});
when(resourceResolverFactory.getMapRoot()).thenReturn(MapEntries.DEFAULT_MAP_ROOT);
when(resourceResolverFactory.getMaxCachedVanityPathEntries()).thenReturn(-1L);
@@ -137,7 +125,7 @@ public class MapEntriesTest {
when(resourceResolver.findResources(anyString(), eq("sql"))).thenReturn(
Collections.<Resource> emptySet().iterator());
- mapEntries = new MapEntries(resourceResolverFactory, bundleContext, eventAdmin);
+ mapEntries = new MapEntries(resourceResolverFactory, bundleContext, eventAdmin, stringInterpolationProvider);
final Field aliasMapField = MapEntries.class.getDeclaredField("aliasMap");
aliasMapField.setAccessible(true);
@@ -150,8 +138,8 @@ public class MapEntriesTest {
}
- @Test(timeout = 1000)
- public void test_simple_alias_support() throws InterruptedException {
+ @Test
+ public void test_simple_alias_support() {
Resource parent = mock(Resource.class);
when(parent.getPath()).thenReturn("/parent");
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImplTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImplTest.java
index 58263b6..479ff0e 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImplTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImplTest.java
@@ -81,7 +81,8 @@ public class ResourceMapperImplTest {
ctx.registerInjectActivateService(new ServiceUserMapperImpl());
ctx.registerInjectActivateService(new ResourceAccessSecurityTracker());
-
+ ctx.registerInjectActivateService(new StringInterpolationProviderImpl());
+
InMemoryResourceProvider resourceProvider = new InMemoryResourceProvider();
resourceProvider.putResource("/"); // root
resourceProvider.putResource("/here"); // regular page
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationMapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationMapEntriesTest.java
index 680dd36..9aa5d05 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationMapEntriesTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationMapEntriesTest.java
@@ -33,7 +33,7 @@ public class StringInterpolationMapEntriesTest extends AbstractMappingMapEntries
public void simple_node_string_interpolation() throws Exception {
// To avoid side effects the String Interpolation uses its own Resource Resolver
Resource sivOne = setupEtcMapResource("${siv.one}", http,PROP_REDIRECT_EXTERNAL, "/content/simple-node");
- setupStringInterpolationProvider(stringInterpolationProvider, stringInterpolationProviderConfiguration, bundleContext, new String[] {"siv.one=test-simple-node"});
+ setupStringInterpolationProvider(stringInterpolationProvider, stringInterpolationProviderConfiguration, new String[] {"siv.one=test-simple-node"});
mapEntries.doInit();
ExpectedEtcMapping expectedEtcMapping = new ExpectedEtcMapping("^http/test-simple-node/", "/content/simple-node/");
@@ -47,7 +47,7 @@ public class StringInterpolationMapEntriesTest extends AbstractMappingMapEntries
PROP_REG_EXP, "${siv.one}/",
PROP_REDIRECT_EXTERNAL, "/content/simple-match/"
);
- setupStringInterpolationProvider(stringInterpolationProvider, stringInterpolationProviderConfiguration, bundleContext, new String[] {"siv.one=test-simple-match"});
+ setupStringInterpolationProvider(stringInterpolationProvider, stringInterpolationProviderConfiguration, new String[] {"siv.one=test-simple-match"});
mapEntries.doInit();
ExpectedEtcMapping expectedEtcMapping = new ExpectedEtcMapping("^http/test-simple-match/", "/content/simple-match/");
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProviderImplTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProviderImplTest.java
index 212c928..3c0b461 100644
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProviderImplTest.java
+++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/StringInterpolationProviderImplTest.java
@@ -18,16 +18,18 @@
*/
package org.apache.sling.resourceresolver.impl.mapping;
+import org.apache.commons.lang3.text.StrSubstitutor;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.osgi.framework.BundleContext;
+import java.util.HashMap;
+import java.util.Map;
+
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
-import static org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider.PLACEHOLDER_START_TOKEN;
-import static org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider.PLACEHOLDER_END_TOKEN;
public class StringInterpolationProviderImplTest {
@@ -41,6 +43,19 @@ public class StringInterpolationProviderImplTest {
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
+ when(stringInterpolationProviderConfiguration.substitution_prefix()).thenReturn("${");
+ when(stringInterpolationProviderConfiguration.substitution_suffix()).thenReturn("}");
+ when(stringInterpolationProviderConfiguration.substitution_escape_character()).thenReturn('$');
+ when(stringInterpolationProviderConfiguration.substitution_in_variables()).thenReturn(false);
+ }
+
+ @Test
+ public void test_strsubstitutor() {
+ Map<String,String> values = new HashMap<>();
+ values.put("one", "two");
+ StrSubstitutor substitutor = new StrSubstitutor(values, "${", "}", '$');
+ String substitude = substitutor.replace("${one}");
+ assertEquals("Wrong Replacement", "two", substitude);
}
@Test
@@ -50,13 +65,11 @@ public class StringInterpolationProviderImplTest {
);
StringInterpolationProviderImpl placeholderProvider = new StringInterpolationProviderImpl();
- placeholderProvider.activate(bundleContext, stringInterpolationProviderConfiguration);
+ placeholderProvider.activate(stringInterpolationProviderConfiguration);
- String line = PLACEHOLDER_START_TOKEN + "one" + PLACEHOLDER_END_TOKEN;
- StringInterpolationProvider.Check check = placeholderProvider.hasPlaceholder(line);
- assertEquals("Wrong Check status", StringInterpolationProvider.STATUS.found, check.getStatus());
- String resolved = placeholderProvider.resolve(check);
- assertEquals("Wrong resolved line", "two", resolved);
+ String line = "${one}";
+ String substituted = placeholderProvider.substitute(line);
+ assertEquals("Wrong resolved line", "two", substituted);
}
@Test
@@ -65,13 +78,11 @@ public class StringInterpolationProviderImplTest {
new String[] { "one=two"}
);
StringInterpolationProviderImpl placeholderProvider = new StringInterpolationProviderImpl();
- placeholderProvider.activate(bundleContext, stringInterpolationProviderConfiguration);
+ placeholderProvider.activate(stringInterpolationProviderConfiguration);
- String line = "Here is " + PLACEHOLDER_START_TOKEN + "one" + PLACEHOLDER_END_TOKEN + ", too";
- StringInterpolationProvider.Check check = placeholderProvider.hasPlaceholder(line);
- assertEquals("Wrong Check status", StringInterpolationProvider.STATUS.found, check.getStatus());
- String resolved = placeholderProvider.resolve(check);
- assertEquals("Wrong resolved line", "Here is two, too", resolved);
+ String line = "Here is ${one}, too";
+ String substituted = placeholderProvider.substitute(line);
+ assertEquals("Wrong resolved line", "Here is two, too", substituted);
}
@Test
@@ -80,13 +91,11 @@ public class StringInterpolationProviderImplTest {
new String[] { "one=two", "three=four"}
);
StringInterpolationProviderImpl placeholderProvider = new StringInterpolationProviderImpl();
- placeholderProvider.activate(bundleContext, stringInterpolationProviderConfiguration);
+ placeholderProvider.activate(stringInterpolationProviderConfiguration);
- String line = PLACEHOLDER_START_TOKEN + "one" + PLACEHOLDER_END_TOKEN + " with another " + PLACEHOLDER_START_TOKEN + "three" + PLACEHOLDER_END_TOKEN;
- StringInterpolationProvider.Check check = placeholderProvider.hasPlaceholder(line);
- assertEquals("Wrong Check status", StringInterpolationProvider.STATUS.found, check.getStatus());
- String resolved = placeholderProvider.resolve(check);
- assertEquals("Wrong resolved line", "two with another four", resolved);
+ String line = "${one} with another ${three}";
+ String substituted = placeholderProvider.substitute(line);
+ assertEquals("Wrong resolved line", "two with another four", substituted);
}
@Test
@@ -96,13 +105,11 @@ public class StringInterpolationProviderImplTest {
);
StringInterpolationProviderImpl placeholderProvider = new StringInterpolationProviderImpl();
- placeholderProvider.activate(bundleContext, stringInterpolationProviderConfiguration);
+ placeholderProvider.activate(stringInterpolationProviderConfiguration);
- String line = "Here comes " + PLACEHOLDER_START_TOKEN + "one" + PLACEHOLDER_END_TOKEN + " with another " + PLACEHOLDER_START_TOKEN + "three" + PLACEHOLDER_END_TOKEN + " equals " + PLACEHOLDER_START_TOKEN + "five" + PLACEHOLDER_END_TOKEN + ", horray!";
- StringInterpolationProvider.Check check = placeholderProvider.hasPlaceholder(line);
- assertEquals("Wrong Check status", StringInterpolationProvider.STATUS.found, check.getStatus());
- String resolved = placeholderProvider.resolve(check);
- assertEquals("Wrong resolved line", "Here comes two with another four equals six, horray!", resolved);
+ String line = "Here comes ${one} with another ${three} equals ${five}, horray!";
+ String substituted = placeholderProvider.substitute(line);
+ assertEquals("Wrong resolved line", "Here comes two with another four equals six, horray!", substituted);
}
@Test
@@ -112,13 +119,11 @@ public class StringInterpolationProviderImplTest {
);
StringInterpolationProviderImpl placeholderProvider = new StringInterpolationProviderImpl();
- placeholderProvider.activate(bundleContext, stringInterpolationProviderConfiguration);
+ placeholderProvider.activate(stringInterpolationProviderConfiguration);
String line = "Here comes is a text with no placeholders!";
- StringInterpolationProvider.Check check = placeholderProvider.hasPlaceholder(line);
- assertEquals("Wrong Check status", StringInterpolationProvider.STATUS.none, check.getStatus());
- String resolved = placeholderProvider.resolve(check);
- assertEquals("Wrong resolved line", "Here comes is a text with no placeholders!", resolved);
+ String substituted = placeholderProvider.substitute(line);
+ assertEquals("Wrong resolved line", "Here comes is a text with no placeholders!", substituted);
}
@Test
@@ -128,13 +133,11 @@ public class StringInterpolationProviderImplTest {
);
StringInterpolationProviderImpl placeholderProvider = new StringInterpolationProviderImpl();
- placeholderProvider.activate(bundleContext, stringInterpolationProviderConfiguration);
+ placeholderProvider.activate(stringInterpolationProviderConfiguration);
- String line = "Here comes " + PLACEHOLDER_START_TOKEN + "unkown" + PLACEHOLDER_END_TOKEN + " placeholders!";
- StringInterpolationProvider.Check check = placeholderProvider.hasPlaceholder(line);
- assertEquals("Wrong Check status", StringInterpolationProvider.STATUS.unknown, check.getStatus());
- String resolved = placeholderProvider.resolve(check);
- assertEquals("Wrong resolved line", "Here comes ${unkown} placeholders!", resolved);
+ String line = "Here comes ${unkown} placeholders!";
+ String substituted = placeholderProvider.substitute(line);
+ assertEquals("Wrong resolved line", "Here comes ${unkown} placeholders!", substituted);
}
@Test
@@ -144,12 +147,71 @@ public class StringInterpolationProviderImplTest {
);
StringInterpolationProviderImpl placeholderProvider = new StringInterpolationProviderImpl();
- placeholderProvider.activate(bundleContext, stringInterpolationProviderConfiguration);
+ placeholderProvider.activate(stringInterpolationProviderConfiguration);
+
+ String line = "${siv.one}/";
+ String substituted = placeholderProvider.substitute(line);
+ assertEquals("Wrong resolved line", "test-value/", substituted);
+ }
+
+ @Test
+ public void test_different_suffix_prefix() {
+ when(stringInterpolationProviderConfiguration.place_holder_key_value_pairs()).thenReturn(
+ new String[] { "test-me.one=hello"}
+ );
+ when(stringInterpolationProviderConfiguration.substitution_prefix()).thenReturn("{{");
+ when(stringInterpolationProviderConfiguration.substitution_suffix()).thenReturn("}}");
+
+ StringInterpolationProviderImpl placeholderProvider = new StringInterpolationProviderImpl();
+ placeholderProvider.activate(stringInterpolationProviderConfiguration);
+
+ String line = "a-{{test-me.one}}-a";
+ String substituted = placeholderProvider.substitute(line);
+ assertEquals("Wrong resolved line", "a-hello-a", substituted);
+ }
+
+ @Test
+ public void test_escape_character() {
+ when(stringInterpolationProviderConfiguration.place_holder_key_value_pairs()).thenReturn(
+ new String[] { "one=two"}
+ );
+ when(stringInterpolationProviderConfiguration.substitution_escape_character()).thenReturn('\\');
+
+ StringInterpolationProviderImpl placeholderProvider = new StringInterpolationProviderImpl();
+ placeholderProvider.activate(stringInterpolationProviderConfiguration);
+
+ String line = "\\${one}=${one}";
+ String substituted = placeholderProvider.substitute(line);
+ assertEquals("Wrong resolved line", "${one}=two", substituted);
+ }
+
+ @Test
+ public void test_in_variables_substitution() {
+ when(stringInterpolationProviderConfiguration.place_holder_key_value_pairs()).thenReturn(
+ new String[] { "one=two", "two=three"}
+ );
+ when(stringInterpolationProviderConfiguration.substitution_in_variables()).thenReturn(true);
+
+ StringInterpolationProviderImpl placeholderProvider = new StringInterpolationProviderImpl();
+ placeholderProvider.activate(stringInterpolationProviderConfiguration);
+
+ String line = "${${one}}";
+ String substituted = placeholderProvider.substitute(line);
+ assertEquals("Wrong resolved line", "three", substituted);
+ }
+
+ @Test
+ public void test_in_variables_substitution2() {
+ when(stringInterpolationProviderConfiguration.place_holder_key_value_pairs()).thenReturn(
+ new String[] { "one=two", "onetwo=three"}
+ );
+ when(stringInterpolationProviderConfiguration.substitution_in_variables()).thenReturn(true);
+
+ StringInterpolationProviderImpl placeholderProvider = new StringInterpolationProviderImpl();
+ placeholderProvider.activate(stringInterpolationProviderConfiguration);
- String line = PLACEHOLDER_START_TOKEN + "siv.one" + PLACEHOLDER_END_TOKEN + "/";
- StringInterpolationProvider.Check check = placeholderProvider.hasPlaceholder(line);
- assertEquals("Wrong Check status", StringInterpolationProvider.STATUS.found, check.getStatus());
- String resolved = placeholderProvider.resolve(check);
- assertEquals("Wrong resolved line", "test-value/", resolved);
+ String line = "${one${one}}";
+ String substituted = placeholderProvider.substitute(line);
+ assertEquals("Wrong resolved line", "three", substituted);
}
}
diff --git a/src/test/java/org/apache/sling/resourceresolver/util/MockTestUtil.java b/src/test/java/org/apache/sling/resourceresolver/util/MockTestUtil.java
index 3f36327..d40bcf6 100644
--- a/src/test/java/org/apache/sling/resourceresolver/util/MockTestUtil.java
+++ b/src/test/java/org/apache/sling/resourceresolver/util/MockTestUtil.java
@@ -26,21 +26,15 @@ import org.apache.sling.api.wrappers.ValueMapDecorator;
import org.apache.sling.resourceresolver.impl.SimpleValueMapImpl;
import org.apache.sling.resourceresolver.impl.helper.RedirectResource;
import org.apache.sling.resourceresolver.impl.mapping.MapEntry;
-<<<<<<< HEAD
import org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider;
import org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProviderConfiguration;
-=======
->>>>>>> master
import org.apache.sling.spi.resource.provider.ResolveContext;
import org.apache.sling.spi.resource.provider.ResourceContext;
import org.apache.sling.spi.resource.provider.ResourceProvider;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-<<<<<<< HEAD
import org.osgi.framework.BundleContext;
-=======
->>>>>>> master
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
@@ -48,10 +42,15 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import static java.util.Arrays.asList;
+import static org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider.DEFAULT_ESCAPE_CHARACTER;
+import static org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider.DEFAULT_IN_VARIABLE_SUBSTITUTION;
+import static org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider.DEFAULT_PREFIX;
+import static org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider.DEFAULT_SUFFIX;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@@ -81,12 +80,6 @@ public class MockTestUtil {
}
public static void checkInternalResource(Resource internal, String path) {
-<<<<<<< HEAD
-// assertThat("Not a Non Existing Resource", redirect, instanceOf(NonExistingResource.class));
-// NonExistingResource nonExistingResource = (NonExistingResource) redirect;
-// if(path != null) {
-=======
->>>>>>> master
assertEquals("Wrong Path for Resource", path, internal.getPath());
}
@@ -141,11 +134,7 @@ public class MockTestUtil {
* @param resourceResolver Resource Resolver of this resource
* @param provider Resource Provider Instance
* @param properties Key / Value pair for resource properties (the number of strings must be even)
-<<<<<<< HEAD
- * @return
-=======
* @return Mock Resource able to handle addition of children later on
->>>>>>> master
*/
@SuppressWarnings("unchecked")
public static Resource buildResource(String fullPath, Resource parent, ResourceResolver resourceResolver, ResourceProvider<?> provider, String... properties) {
@@ -201,25 +190,6 @@ public class MockTestUtil {
return resource;
}
-<<<<<<< HEAD
- public static Object callInaccessibleMethod(String methodName, Object target, Class paramsType, Object param) throws NoSuchMethodException {
- return callInaccessibleMethod(methodName, target, new Class[] {paramsType}, new Object[] {param});
- }
-
- public static Object callInaccessibleMethod(String methodName, Object target, Class[] paramsTypes, Object[] params) throws NoSuchMethodException {
- if(paramsTypes != null && params != null) {
- if(params.length != paramsTypes.length) { throw new IllegalArgumentException("Number of Parameter Types and Values were not the same"); }
- } else {
- paramsTypes = null;
- params = null;
- }
- try {
- Method method = target.getClass().getDeclaredMethod(methodName, paramsTypes);
- method.setAccessible(true);
- return method.invoke(target, params);
- } catch(NoSuchMethodException e) {
- throw new UnsupportedOperationException("Failed to find method: " + methodName, e);
-=======
/**
* Calls a private method that has no parameter like a getter
*
@@ -271,7 +241,6 @@ public class MockTestUtil {
}
try {
return getInaccessibleMethod(methodName, returnType, target, parameterTypes).call(parameters);
->>>>>>> master
} catch (IllegalAccessException e) {
throw new UnsupportedOperationException("Failed to access method: " + methodName, e);
} catch (InvocationTargetException e) {
@@ -279,28 +248,6 @@ public class MockTestUtil {
}
}
-<<<<<<< HEAD
- public static void setInaccessibleField(String fieldName, Object target, Object fieldValue) throws NoSuchMethodException {
- try {
- Field field = target.getClass().getDeclaredField(fieldName);
- field.setAccessible(true);
- field.set(target, fieldValue);
- } catch (IllegalAccessException e) {
- throw new UnsupportedOperationException("Failed to access field: " + fieldName, e);
- } catch (NoSuchFieldException e) {
- e.printStackTrace();
- }
- }
-
- public static void setupStringInterpolationProvider(
- StringInterpolationProvider provider, StringInterpolationProviderConfiguration configuration, BundleContext bundleContext, final String[] placeholderValues
- ) throws NoSuchMethodException {
- when(configuration.place_holder_key_value_pairs()).thenReturn(placeholderValues);
- callInaccessibleMethod("activate", provider,
- new Class[] {BundleContext.class, StringInterpolationProviderConfiguration.class},
- new Object[] {bundleContext, configuration}
- );
-=======
public static <T> MethodWrapper<T> getInaccessibleMethod(String methodName, Class<T> returnType, Object target, Class...parameterTypes) {
return new MethodWrapper(methodName, returnType, target, parameterTypes);
}
@@ -363,6 +310,26 @@ public class MockTestUtil {
}
}
+ public static StringInterpolationProviderConfiguration createStringInterpolationProviderConfiguration() {
+ StringInterpolationProviderConfiguration answer = mock(StringInterpolationProviderConfiguration.class);
+ when(answer.substitution_prefix()).thenReturn(DEFAULT_PREFIX);
+ when(answer.substitution_suffix()).thenReturn(DEFAULT_SUFFIX);
+ when(answer.substitution_escape_character()).thenReturn(DEFAULT_ESCAPE_CHARACTER);
+ when(answer.substitution_in_variables()).thenReturn(DEFAULT_IN_VARIABLE_SUBSTITUTION);
+ when(answer.place_holder_key_value_pairs()).thenReturn(new String[] {});
+ return answer;
+ }
+
+ public static void setupStringInterpolationProvider(
+ StringInterpolationProvider provider, StringInterpolationProviderConfiguration configuration, final String[] placeholderValues
+ ) {
+ when(configuration.place_holder_key_value_pairs()).thenReturn(placeholderValues);
+ callInaccessibleMethod("activate", Void.TYPE, provider,
+ new Class[] {StringInterpolationProviderConfiguration.class},
+ new Object[] {configuration}
+ );
+ }
+
public static class FieldWrapper<T> {
private Field field;
private Object target;
@@ -380,7 +347,6 @@ public class MockTestUtil {
public T get() throws IllegalAccessException {
return (T) field.get(target);
}
->>>>>>> master
}
/**
@@ -392,12 +358,9 @@ public class MockTestUtil {
public List<Resource> getChildrenList();
}
-<<<<<<< HEAD
-=======
/**
* Defines the Result of the Etc Mapping for easy testing
*/
->>>>>>> master
public static class ExpectedEtcMapping {
List<ExpectedEtcMapEntry> expectedEtcMapEntries = new ArrayList<>();