IllegalArgumentException occurs on screen with FileUploadField in UberJAR #896

This commit is contained in:
Yuriy Artamonov 2018-05-29 18:16:32 +04:00
parent bd7adbe7bb
commit 914b2487eb
5 changed files with 197 additions and 28 deletions

View File

@ -23,7 +23,6 @@ import com.vaadin.server.BootstrapListener;
import com.vaadin.server.BootstrapPageResponse;
import org.jsoup.nodes.Element;
import org.springframework.stereotype.Component;
import org.webjars.WebJarAssetLocator;
import javax.inject.Inject;
@ -49,7 +48,7 @@ public class CubaBootstrapListener implements BootstrapListener {
public void modifyBootstrapPage(BootstrapPageResponse response) {
Element head = response.getDocument().getElementsByTag("head").get(0);
includeScript(getWebJarResource("jquery.min.js"), response, head);
includeScript(getWebJarResource("jquery", "jquery.min.js"), response, head);
int customDeviceWidthForViewport = webConfig.getCustomDeviceWidthForViewport();
if (customDeviceWidthForViewport > 0) {
@ -62,8 +61,13 @@ public class CubaBootstrapListener implements BootstrapListener {
}
protected String getWebJarResource(String resourceName) {
return new WebJarAssetLocator().getFullPath(resourceName)
.replace("META-INF/resources", "VAADIN");
String fullPath = WebJarResourceUtils.getWebJarPath(resourceName);
return "./" + WebJarResourceUtils.translateToWebPath(fullPath);
}
protected String getWebJarResource(String webjar, String resourceName) {
String fullPath = WebJarResourceUtils.getWebJarPath(webjar, resourceName);
return "./" + WebJarResourceUtils.translateToWebPath(fullPath);
}
protected void includeScript(String src, BootstrapPageResponse response, Element head) {

View File

@ -27,7 +27,6 @@ import com.vaadin.ui.UI;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.webjars.WebJarAssetLocator;
import javax.servlet.ServletContext;
import java.io.IOException;
@ -42,14 +41,8 @@ public class CubaUidlWriter extends UidlWriter {
private static final Logger log = LoggerFactory.getLogger(CubaUidlWriter.class);
// Thread safe
public static final WebJarAssetLocator webJarAssetLocator = new WebJarAssetLocator();
protected static final String JAVASCRIPT_EXTENSION = ".js";
protected static final String CSS_EXTENSION = ".css";
protected static final String VAADIN_PREFIX = "VAADIN/";
protected static final String VAADIN_WEBJARS_PREFIX = "/" + VAADIN_PREFIX + "webjars/";
protected static final String META_INF_PREFIX = "META-INF/resources/";
protected static final Pattern OLD_WEBJAR_IDENTIFIER = Pattern.compile("([^:]+)/.+/(.+)");
protected static final Pattern NEW_WEBJAR_IDENTIFIER = Pattern.compile("(.+):(.+)");
@ -126,8 +119,8 @@ public class CubaUidlWriter extends UidlWriter {
return staticResourcePath;
}
return webJarAssetLocator.getFullPath(webJar, resource)
.replace(META_INF_PREFIX, VAADIN_PREFIX);
String webJarPath = WebJarResourceUtils.getWebJarPath(webJar, resource);
return WebJarResourceUtils.translateToWebPath(webJarPath);
}
protected String getWebJarStaticResourcePath(String overridePath, String resource) {
@ -140,7 +133,7 @@ public class CubaUidlWriter extends UidlWriter {
}
String resourcePath = overridePath + resource;
String path = VAADIN_WEBJARS_PREFIX + resourcePath;
String path = CubaWebJarsHandler.VAADIN_WEBJARS_PREFIX + resourcePath;
URL resourceUrl = null;
try {
@ -174,13 +167,13 @@ public class CubaUidlWriter extends UidlWriter {
}
if (StringUtils.isEmpty(webJarVersion)) {
String msg = String.format("Could not load WebJar version property value: %s. And default version is also not set",
String msg = String.format("Unable to load WebJar version property value: %s. Default version is not set",
propertyName);
log.error(msg);
throw new RuntimeException(msg);
}
return uri.replace("${" + propertyName + "}", webJarVersion);
return StringUtils.replace(uri, "${" + propertyName + "}", webJarVersion);
}
}

View File

@ -24,7 +24,6 @@ import com.vaadin.server.VaadinSession;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.webjars.WebJarAssetLocator;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
@ -38,18 +37,13 @@ import static org.apache.commons.io.IOUtils.copy;
public class CubaWebJarsHandler implements RequestHandler {
protected static final String VAADIN_WEBJARS_PREFIX = "/VAADIN/webjars/";
protected static final String VAADIN_PREFIX = "/VAADIN/";
protected static final String CLASSPATH_WEBJAR_PREFIX = "/META-INF/resources/";
private final Logger log = LoggerFactory.getLogger(CubaWebJarsHandler.class);
protected ServletContext servletContext;
protected WebJarAssetLocator webJarAssetLocator;
public CubaWebJarsHandler(ServletContext servletContext) {
this.servletContext = servletContext;
this.webJarAssetLocator = new WebJarAssetLocator();
}
@Override
@ -166,7 +160,7 @@ public class CubaWebJarsHandler implements RequestHandler {
}
protected URL getClassPathResourceUrl(String path) {
String classpathPath = path.replace(VAADIN_PREFIX, CLASSPATH_WEBJAR_PREFIX);
String classpathPath = WebJarResourceUtils.translateToClassPath(path);
log.trace("Load WebJar resource from classpath: {}", classpathPath);

View File

@ -0,0 +1,180 @@
/*
* Copyright (c) 2008-2018 Haulmont.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.haulmont.cuba.web.sys;
import com.haulmont.cuba.core.sys.AppContext;
import org.apache.commons.lang3.StringUtils;
import org.webjars.MultipleMatchesException;
import org.webjars.WebJarAssetLocator;
import java.util.*;
import java.util.regex.Pattern;
/**
* Utility class for WebJar resources management.
*/
public final class WebJarResourceUtils {
// Thread safe
public static final WebJarAssetLocator locator = new WebJarAssetLocator(
WebJarAssetLocator.getFullPathIndex(Pattern.compile(".*"),
WebJarResourceUtils.class.getClassLoader())
); // use web application class loader instead of shared
public static final String WEBJARS_PATH_PREFIX = "META-INF/resources/webjars";
public static final String UBERJAR_WEBJARS_PATH_PREFIX = "LIB-INF/shared/META-INF/resources/webjars";
public static final String VAADIN_PREFIX = "VAADIN/";
public static final String CLASSPATH_WEBJAR_PREFIX = "META-INF/resources/";
public static final String UBERJAR_CLASSPATH_WEBJAR_PREFIX = "LIB-INF/shared/META-INF/resources/";
private WebJarResourceUtils() {
}
/**
* @param webjar The id of the WebJar to search
* @param partialPath The partial path to look for
* @return a fully qualified path to the resource
*/
public static String getWebJarPath(String webjar, String partialPath) {
SortedMap<String, String> index = locator.getFullPathIndex();
String searchPath;
if (isUberJar()) {
searchPath = UBERJAR_WEBJARS_PATH_PREFIX + "/" + webjar + "/";
} else {
searchPath = WEBJARS_PATH_PREFIX + "/" + webjar + "/";
}
return getFullPath(filterPathIndexByPrefix(index, searchPath), partialPath);
}
/**
* @param partialPath the path to return e.g. "jquery.js".
* @return a fully qualified path to the resource.
*/
public static String getWebJarPath(String partialPath) {
return locator.getFullPath(partialPath);
}
/**
* @param fullWebJarPath WebJar resource location in ClassPath
* @return path for web page with VAADIN subfolder
*/
public static String translateToWebPath(String fullWebJarPath) {
if (isUberJar()) {
return StringUtils.replace(fullWebJarPath, UBERJAR_CLASSPATH_WEBJAR_PREFIX, VAADIN_PREFIX);
}
return StringUtils.replace(fullWebJarPath, CLASSPATH_WEBJAR_PREFIX, VAADIN_PREFIX);
}
/**
* @param fullVaadinPath path for web page with VAADIN subfolder
* @return WebJar resource location in ClassPath
*/
public static String translateToClassPath(String fullVaadinPath) {
if (isUberJar()) {
return StringUtils.replace(fullVaadinPath, VAADIN_PREFIX, UBERJAR_CLASSPATH_WEBJAR_PREFIX);
}
return StringUtils.replace(fullVaadinPath, VAADIN_PREFIX, CLASSPATH_WEBJAR_PREFIX);
}
private static boolean isUberJar() {
return Boolean.parseBoolean(AppContext.getProperty("cuba.uberJar"));
}
// CAUTION: copied from WebJarAssetLocator
private static SortedMap<String, String> filterPathIndexByPrefix(SortedMap<String, String> pathIndex, String prefix) {
SortedMap<String, String> filteredPathIndex = new TreeMap<>();
for (String key : pathIndex.keySet()) {
String value = pathIndex.get(key);
if (value.startsWith(prefix)) {
filteredPathIndex.put(key, value);
}
}
return filteredPathIndex;
}
// CAUTION: copied from WebJarAssetLocator
private static String getFullPath(SortedMap<String, String> pathIndex, String partialPath) {
if (partialPath.charAt(0) == '/') {
partialPath = partialPath.substring(1);
}
final String reversePartialPath = reversePath(partialPath);
final SortedMap<String, String> fullPathTail = pathIndex.tailMap(reversePartialPath);
if (fullPathTail.size() == 0) {
throwNotFoundException(partialPath);
}
final Iterator<Map.Entry<String, String>> fullPathTailIter = fullPathTail
.entrySet().iterator();
final Map.Entry<String, String> fullPathEntry = fullPathTailIter.next();
if (!fullPathEntry.getKey().startsWith(reversePartialPath)) {
throwNotFoundException(partialPath);
}
final String fullPath = fullPathEntry.getValue();
if (fullPathTailIter.hasNext()) {
List<String> matches = null;
while (fullPathTailIter.hasNext()) {
Map.Entry<String, String> next = fullPathTailIter.next();
if (next.getKey().startsWith(reversePartialPath)) {
if (matches == null) {
matches = new ArrayList<>();
}
matches.add(next.getValue());
} else {
break;
}
}
if (matches != null) {
matches.add(fullPath);
throw new MultipleMatchesException(
"Multiple matches found for "
+ partialPath
+ ". Please provide a more specific path, for example by including a version number.", matches);
}
}
return fullPath;
}
// CAUTION: copied from WebJarAssetLocator
private static void throwNotFoundException(final String partialPath) {
throw new IllegalArgumentException(
partialPath
+ " could not be found. Make sure you've added the corresponding WebJar and please check for typos."
);
}
// CAUTION: copied from WebJarAssetLocator
private static String reversePath(String assetPath) {
final String[] assetPathComponents = assetPath.split("/");
final StringBuilder reversedAssetPath = new StringBuilder();
for (int i = assetPathComponents.length - 1; i >= 0; --i) {
reversedAssetPath.append(assetPathComponents[i]);
reversedAssetPath.append('/');
}
return reversedAssetPath.toString();
}
}

View File

@ -18,6 +18,7 @@
package com.haulmont.cuba.web.toolkit.ui;
import com.haulmont.cuba.web.sys.WebJarResource;
import com.haulmont.cuba.web.sys.WebJarResourceUtils;
import com.haulmont.cuba.web.toolkit.ui.client.multiupload.CubaMultiUploadServerRpc;
import com.haulmont.cuba.web.toolkit.ui.client.multiupload.CubaMultiUploadState;
import com.vaadin.server.*;
@ -25,7 +26,6 @@ import com.vaadin.ui.LegacyComponent;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.LoggerFactory;
import org.webjars.WebJarAssetLocator;
import java.io.OutputStream;
import java.io.Serializable;
@ -212,12 +212,10 @@ public class CubaMultiUpload extends CubaAbstractUploadComponent implements Lega
public CubaMultiUpload() {
registerRpc(rpc);
WebJarAssetLocator webJarAssetLocator = new WebJarAssetLocator();
String swfuploadJs = webJarAssetLocator.getFullPath("swfupload", "swfupload.min.js");
String swfuploadJs = WebJarResourceUtils.getWebJarPath("swfupload", "swfupload.min.js");
setResource(CubaMultiUploadState.SWFUPLOAD_BOOTSTRAP_JS_KEY, new ClassResource(swfuploadJs));
String swfuploadSwf = webJarAssetLocator.getFullPath("swfupload", "swfupload.swf");
String swfuploadSwf = WebJarResourceUtils.getWebJarPath("swfupload", "swfupload.swf");
setResource(CubaMultiUploadState.SWFUPLOAD_FLASH_KEY, new ClassResource(swfuploadSwf));
}