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 <[email protected]> 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<>();
