/*
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package com.mpalourdio.html5.config;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.resource.PathResourceResolver;
import org.springframework.web.servlet.resource.TransformedResource;

import java.io.IOException;

@Configuration
public class SinglePageAppConfig extends WebMvcConfigurerAdapter {

    private final String apiPath;
    private final String contextPath;
    private final ResourceProperties resourceProperties;

    public SinglePageAppConfig(
            @Value("${apiPath}") final String apiPath,
            @Value("${server.contextPath}") final String contextPath,
            final ResourceProperties resourceProperties
    ) {
        this.apiPath = apiPath;
        this.contextPath = contextPath;
        this.resourceProperties = resourceProperties;
    }

    @Override
    public void addResourceHandlers(final ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/")
                .setCachePeriod(resourceProperties.getCachePeriod())
                .resourceChain(true)
                .addResolver(new SinglePageAppResourceResolver());
    }

    private class SinglePageAppResourceResolver extends PathResourceResolver {

        @Override
        protected Resource getResource(final String resourcePath, final Resource location) throws IOException {
            Resource resource = location.createRelative(resourcePath);
            if (resource.exists() && resource.isReadable()) {
                return resource;
            }

            if (apiPath != null && ("/" + resourcePath).startsWith(apiPath)) {
                return null;
            }

            resource = location.createRelative("index.html");
            if (resource.exists() && resource.isReadable()) {
                String html = IOUtils.toString(resource.getInputStream(), "UTF-8");
                html = html.replace("#context-path#", contextPath + "/");
                return new TransformedResource(resource, html.getBytes());
            }

            return null;
        }
    }
}

@@ -1211,32 +1211,39 @@
  %7B%0A%0A    private 
+static 
 final String api
@@ -1239,24 +1239,376 @@
  String 
-apiPath;
+API_PATH = %22/api%22;%0A    private static final String PATH_PATTERNS = %22/**%22;%0A    private static final String FRONT_CONTROLLER = %22index.html%22;%0A    private static final String RESOURCES_LOCATION = %22classpath:/static/%22;%0A    private static final String CONTEXT_PATH_PLACEHOLDER = %22#context-path#%22;%0A    private static final String FRONT_CONTROLLER_ENCODING = %22UTF-8%22;%0A
 %0A    pri
@@ -1732,63 +1732,8 @@
 ig(%0A
-            @Value(%22$%7BapiPath%7D%22) final String apiPath,%0A
     
@@ -1866,40 +1866,8 @@
 ) %7B%0A
-        this.apiPath = apiPath;%0A
     
@@ -2091,21 +2091,29 @@
 Handler(
-%22/**%22
+PATH_PATTERNS
 )%0A      
@@ -2144,36 +2144,34 @@
 cations(
-%22classpath:/static/%22
+RESOURCES_LOCATION
 )%0A      
@@ -2755,27 +2755,8 @@
 if (
-apiPath != null && 
 (%22/%22
@@ -2787,15 +2787,16 @@
 ith(
-apiPath
+API_PATH
 )) %7B
@@ -2887,28 +2887,32 @@
 elative(
-%22index.html%22
+FRONT_CONTROLLER
 );%0A     
@@ -2991,20 +2991,27 @@
  String 
-html
+fileContent
  = IOUti
@@ -3053,70 +3053,110 @@
 (), 
-%22UTF-8%22);%0A                html = html.replace(%22#context-path#%22
+FRONT_CONTROLLER_ENCODING);%0A                fileContent = fileContent.replace(CONTEXT_PATH_PLACEHOLDER
 , co
@@ -3230,20 +3230,27 @@
 source, 
-html
+fileContent
 .getByte

Refactor a bit