Skip to content

Commit

Permalink
refactor: simplify ResourceProvider (#9609)
Browse files Browse the repository at this point in the history
fixes #9605
  • Loading branch information
Denis authored Dec 9, 2020
1 parent cb5bc35 commit 89190a5
Show file tree
Hide file tree
Showing 16 changed files with 124 additions and 305 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public void init() {

ResourceProvider resourceProvider = service.getContext()
.getAttribute(Lookup.class).lookup(ResourceProvider.class);
Mockito.when(resourceProvider.getApplicationResource(service,
Mockito.when(resourceProvider.getApplicationResource(
VAADIN_SERVLET_RESOURCES + STATISTICS_JSON_DEFAULT))
.thenReturn(LitTemplateParserImplTest.class.getResource(
"/" + VAADIN_SERVLET_RESOURCES + "config/stats.json"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,7 @@ protected String getSourcesFromTemplate(VaadinService service, String tag,
.lookup(ResourceProvider.class);
InputStream content = null;
try {
URL appResource = resourceProvider.getApplicationResource(service,
url);
URL appResource = resourceProvider.getApplicationResource(url);
content = appResource == null ? null : appResource.openStream();
} catch (IOException exception) {
getLogger().warn("Coudln't get resource for the template '{}'", url,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
*/
package com.vaadin.flow.component.polymertemplate;

import static com.vaadin.flow.server.Constants.STATISTICS_JSON_DEFAULT;
import static com.vaadin.flow.server.Constants.VAADIN_SERVLET_RESOURCES;

import java.util.Locale;
import java.util.Properties;
import java.util.stream.Stream;
Expand All @@ -43,6 +40,9 @@
import com.vaadin.flow.server.MockVaadinServletService;
import com.vaadin.flow.templatemodel.TemplateModel;

import static com.vaadin.flow.server.Constants.STATISTICS_JSON_DEFAULT;
import static com.vaadin.flow.server.Constants.VAADIN_SERVLET_RESOURCES;

public class NpmTemplateParserTest {

private MockVaadinServletService service;
Expand Down Expand Up @@ -77,11 +77,11 @@ public void init() throws Exception {

resourceProvider = service.getContext().getAttribute(Lookup.class)
.lookup(ResourceProvider.class);
Mockito.when(resourceProvider.getApplicationResource(
Mockito.eq(service), Mockito.anyString()))
Mockito.when(
resourceProvider.getApplicationResource(Mockito.anyString()))
.thenAnswer(invocation -> NpmTemplateParserTest.class
.getResource('/'
+ invocation.getArgumentAt(1, String.class)));
+ invocation.getArgumentAt(0, String.class)));
}

@Test
Expand Down Expand Up @@ -109,7 +109,7 @@ public void should_FindCorrectDataInStats() {
public void getTemplateContent_polymer2TemplateStyleInsertion_contentParsedCorrectly() {
ResourceProvider resourceProvider = service.getContext()
.getAttribute(Lookup.class).lookup(ResourceProvider.class);
Mockito.when(resourceProvider.getApplicationResource(service,
Mockito.when(resourceProvider.getApplicationResource(
VAADIN_SERVLET_RESOURCES + STATISTICS_JSON_DEFAULT))
.thenReturn(NpmTemplateParser.class
.getResource("/" + VAADIN_SERVLET_RESOURCES
Expand All @@ -129,7 +129,7 @@ public void getTemplateContent_polymer2TemplateStyleInsertion_contentParsedCorre
public void getTemplateContent_polymer2TemplateStyleInsertion_severalDomModules_correctTemplateContentIsChosen() {
ResourceProvider resourceProvider = service.getContext()
.getAttribute(Lookup.class).lookup(ResourceProvider.class);
Mockito.when(resourceProvider.getApplicationResource(service,
Mockito.when(resourceProvider.getApplicationResource(
VAADIN_SERVLET_RESOURCES + STATISTICS_JSON_DEFAULT))
.thenReturn(NpmTemplateParser.class
.getResource("/" + VAADIN_SERVLET_RESOURCES
Expand Down Expand Up @@ -188,7 +188,7 @@ public void getTypescriptTemplateContent_templateExists_getTemplateContent() {
public void should_throwException_when_LocalFileNotFound() {
ResourceProvider resourceProvider = service.getContext()
.getAttribute(Lookup.class).lookup(ResourceProvider.class);
Mockito.when(resourceProvider.getApplicationResource(service,
Mockito.when(resourceProvider.getApplicationResource(
VAADIN_SERVLET_RESOURCES + STATISTICS_JSON_DEFAULT))
.thenReturn(NpmTemplateParser.class
.getResource("/META-INF/resources/foo-bar.json"));
Expand Down Expand Up @@ -250,7 +250,7 @@ public void nonLocalTemplate_shouldParseCorrectly() {
public void bableStats_shouldAlwaysParseCorrectly() {
ResourceProvider resourceProvider = service.getContext()
.getAttribute(Lookup.class).lookup(ResourceProvider.class);
Mockito.when(resourceProvider.getApplicationResource(service,
Mockito.when(resourceProvider.getApplicationResource(
VAADIN_SERVLET_RESOURCES + STATISTICS_JSON_DEFAULT))
.thenReturn(NpmTemplateParser.class
.getResource("/" + VAADIN_SERVLET_RESOURCES
Expand Down Expand Up @@ -309,7 +309,7 @@ public void bableStats_shouldAlwaysParseCorrectly() {
public void hierarchicalTemplate_templateHasChild_childHasCorrectPosition() {
ResourceProvider resourceProvider = service.getContext()
.getAttribute(Lookup.class).lookup(ResourceProvider.class);
Mockito.when(resourceProvider.getApplicationResource(service,
Mockito.when(resourceProvider.getApplicationResource(
VAADIN_SERVLET_RESOURCES + STATISTICS_JSON_DEFAULT))
.thenReturn(NpmTemplateParser.class
.getResource("/" + VAADIN_SERVLET_RESOURCES
Expand Down
88 changes: 10 additions & 78 deletions flow-server/src/main/java/com/vaadin/flow/di/ResourceProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@
import java.net.URL;
import java.util.List;

import com.vaadin.flow.server.VaadinService;
import com.vaadin.flow.server.VaadinServlet;

/**
* Static "classpath" resources provider.
* <p>
Expand All @@ -38,99 +35,34 @@ public interface ResourceProvider {

/**
* Gets the resource identified by {@code path} located in the application
* bundle (jar) which may be found using the {@code contextClass}.
* bundle (jar) which may be found using this resource provider instance.
* <p>
* If the {@code contextClass} doesn't contain any information about
* application bundle or there is no resource with the given path then this
* method returns {@code null}.
* If the provider doesn't contain any information about application bundle
* or there is no resource with the given path then this method returns
* {@code null}.
*
* @param contextClass
* a class to find an application bundle
* @param path
* the resource path
* @return an URL of the resource, may be {@code null}
*/
URL getApplicationResource(Class<?> contextClass, String path);
URL getApplicationResource(String path);

/**
* Gets all the resources identified by {@code path} located in in the
* application bundle (jar) which may be found using the {@code
* contextClass}.
* <p>
* If the {@code contextClass} doesn't contain any information about
* application bundle or there is no resource with the given path then this
* method returns an empty list.
*
* @param contextClass
* a class to find an application bundle @param path the resource
* path @return a list of URLs of the resources or an empty list
* if resources are not found
* @throws IOException
* if there is an I/O error
*/
List<URL> getApplicationResources(Class<?> contextClass, String path)
throws IOException;

/**
* Gets all the web application resources identified by the {@code path}
* using the provided {@code context}.
* application bundle (jar) which may be found using this resource provider.
* <p>
* The context doesn't have to be in the same bundle as the resource. The
* resource location is the web application bundle (WAR or WAB) which might
* not contain the {@code context} declaration at all. The {@code context}
* instance is only used to find the correct bundle where the resource is
* located.
* <p>
* A typical scenario could be : the {@code context} object is a
* {@link VaadinService} or {@link VaadinServlet} instance and the path is
* some resource in the web application (which is very specific for the
* application), e.g. {@code "stats.json"}. Both {@link VaadinService} and
* {@link VaadinServlet} are located in "flow-server" bundle which doesn't
* know anything about web app specific resources. If a servlet is
* registered manually in the WAB then its bundle may be used to find the
* resource. Otherwise some context information about WAB should be
* retrieved from the {@code context}.
* If the provider doesn't contain any information about application bundle
* or there is no resource with the given path then this method returns an
* empty list.
*
* @param context
* a context object
* @param path
* the resource path
* @return a list of URLs of the resources or an empty list if resources are
* not found
*
* @throws IOException
* if there is an I/O error
*/
List<URL> getApplicationResources(Object context, String path)
throws IOException;

/**
* Gets the web application resource identified by the {@code path} using
* the provided {@code context}.
* <p>
* The context doesn't have to be in the same bundle as the resource. The
* resource location is the web application bundle (WAR or WAB) which might
* not contain the {@code context} declaration at all. The {@code context}
* instance is only used to find the correct bundle where the resource is
* located.
* <p>
* A typical scenario could be : the {@code context} object is a
* {@link VaadinService} or {@link VaadinServlet} instance and the path is
* some resource in the web application (which is very specific for the
* application), e.g. {@code "stats.json"}. Both {@link VaadinService} and
* {@link VaadinServlet} are located in "flow-server" bundle which doesn't
* know anything about web app specific resources. If a servlet is
* registered manually in the WAB then its bundle may be used to find the
* resource. Otherwise some context information about WAB should be
* retrieved from the {@code context}.
*
* @param context
* a context object
* @param path
* the resource path
* @return an URL of the resource, may be {@code null}
*/
URL getApplicationResource(Object context, String path);
List<URL> getApplicationResources(String path) throws IOException;

/**
* Gets "flow-client" bundle resource identified by the {@code path}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,7 @@ private static InputStream getInlineResourceStream(VaadinRequest request,
VaadinService service = request.getService();
ResourceProvider resourceProvider = service.getContext()
.getAttribute(Lookup.class).lookup(ResourceProvider.class);
URL appResource = resourceProvider.getApplicationResource(service,
file);
URL appResource = resourceProvider.getApplicationResource(file);

InputStream stream = null;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
Expand Down Expand Up @@ -314,8 +312,7 @@ private static String getTokenFileContents(Class<?> systemPropertyBaseClass,
try {
json = getResourceFromFile(initParameters);
if (json == null) {
json = getTokenFileFromClassloader(systemPropertyBaseClass,
context);
json = getTokenFileFromClassloader(context);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
Expand All @@ -339,8 +336,7 @@ private static String getResourceFromFile(Properties initParameters)
}

/**
* Gets token file from the classpath using the provided
* {@code contextClass} and {@code context}.
* Gets token file from the classpath using the provided {@code context}.
* <p>
* The {@code contextClass} may be a class which is defined in the Web
* Application module/bundle and in this case it may be used to get Web
Expand All @@ -353,31 +349,23 @@ private static String getResourceFromFile(Properties initParameters)
* can't be used to get Web Application resources since they are in
* different bundles.
*
* @param contextClass
* a context class whose module may contain the token file
* @param context
* a VaadinContext which may provide information how to get token
* file for the web application
* @return the token file content
* @throws IOException
* if I/O fails during access to the token file
*/
private static String getTokenFileFromClassloader(Class<?> contextClass,
VaadinContext context) throws IOException {
private static String getTokenFileFromClassloader(VaadinContext context)
throws IOException {
String tokenResource = VAADIN_SERVLET_RESOURCES + TOKEN_FILE;

Lookup lookup = context.getAttribute(Lookup.class);
ResourceProvider resourceProvider = lookup
.lookup(ResourceProvider.class);

List<URL> classResources = resourceProvider
.getApplicationResources(contextClass, tokenResource);
List<URL> contextResources = resourceProvider
.getApplicationResources(context, tokenResource);

List<URL> resources = Stream
.concat(classResources.stream(), contextResources.stream())
.collect(Collectors.toList());
List<URL> resources = resourceProvider
.getApplicationResources(tokenResource);

// Accept resource that doesn't contain
// 'jar!/META-INF/Vaadin/config/flow-build-info.json'
Expand All @@ -388,7 +376,7 @@ private static String getTokenFileFromClassloader(Class<?> contextClass,
// For no non jar build info, in production mode check for
// webpack.generated.json if it's in a jar then accept
// single jar flow-build-info.
return getPossibleJarResource(contextClass, context, resources);
return getPossibleJarResource(context, resources);
}
return resource == null ? null
: FrontendUtils.streamToString(resource.openStream());
Expand All @@ -403,8 +391,8 @@ private static String getTokenFileFromClassloader(Class<?> contextClass,
* Else we will accept any flow-build-info and log a warning that it may not
* be the correct file, but it's the best we could find.
*/
private static String getPossibleJarResource(Class<?> contextClass,
VaadinContext context, List<URL> resources) throws IOException {
private static String getPossibleJarResource(VaadinContext context,
List<URL> resources) throws IOException {
Objects.requireNonNull(resources);

Lookup lookup = context.getAttribute(Lookup.class);
Expand All @@ -414,12 +402,8 @@ private static String getPossibleJarResource(Class<?> contextClass,
assert !resources
.isEmpty() : "Possible jar resource requires resources to be available.";

URL webpackGenerated = resourceProvider.getApplicationResource(context,
FrontendUtils.WEBPACK_GENERATED);
if (webpackGenerated == null) {
webpackGenerated = resourceProvider.getApplicationResource(
contextClass, FrontendUtils.WEBPACK_GENERATED);
}
URL webpackGenerated = resourceProvider
.getApplicationResource(FrontendUtils.WEBPACK_GENERATED);

// If jar!/ exists 2 times for webpack.generated.json then we are
// running from a jar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ private static InputStream getStatsFromClassPath(VaadinService service) {
.replaceFirst("^/", "");
ResourceProvider resourceProvider = service.getContext()
.getAttribute(Lookup.class).lookup(ResourceProvider.class);
URL statsUrl = resourceProvider.getApplicationResource(service, stats);
URL statsUrl = resourceProvider.getApplicationResource(stats);
InputStream stream = null;
try {
stream = statsUrl == null ? null : statsUrl.openStream();
Expand Down
Loading

0 comments on commit 89190a5

Please sign in to comment.