blob: bfd1a5e4329a05f0ec7d836136504063cef0be3c [file] [log] [blame]
/*
* Copyright (c) 2014-2017 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* BSI Business Systems Integration AG - initial API and implementation
*/
package org.eclipse.scout.rt.ui.html.res;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.scout.rt.client.services.common.icon.IconLocator;
import org.eclipse.scout.rt.client.services.common.icon.IconSpec;
import org.eclipse.scout.rt.platform.resource.BinaryResource;
import org.eclipse.scout.rt.platform.resource.BinaryResourceUtility;
import org.eclipse.scout.rt.platform.util.Pair;
import org.eclipse.scout.rt.platform.util.StringUtility;
import org.eclipse.scout.rt.shared.AbstractIcons;
import org.eclipse.scout.rt.ui.html.json.IJsonAdapter;
import org.eclipse.scout.rt.ui.html.res.loader.DynamicResourceInfo;
import org.eclipse.scout.rt.ui.html.res.loader.DynamicResourceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class BinaryResourceUrlUtility {
private static final Logger LOG = LoggerFactory.getLogger(BinaryResourceUrlUtility.class);
private BinaryResourceUrlUtility() {
}
/**
* Regular expression pattern to find icons, e.g. to find <img src="iconid:some_icon">.
* <p>
* Pattern does a search for iconid:some_icon (in quotation marks) and has three groups:
* <li>1. Type of quotation mark, either " or '.
* <li>2. Icon name, in the example <b>some_icon</b>
*/
public static final Pattern ICON_REGEX_PATTERN = Pattern.compile("([\"'])iconId:([^\"']+)\\1", Pattern.CASE_INSENSITIVE);
/**
* Regular expression pattern to find icons, e.g. to find &lt;img src="binaryresource:some_res"&gt;.
* <p>
* Pattern does a search for binaryResource:some_res (in quotation marks) and has three groups:
* <li>1. Type of quotation mark, either " or '.
* <li>2. Icon name, in the example <b>some_res</b>
*/
public static final Pattern BINARY_RESOURCE_REGEX_PATTERN = Pattern.compile("([\"'])binaryResource:([^\"']+)\\1", Pattern.CASE_INSENSITIVE);
/**
* @return a relative URL for a configured logical icon-name or a font-based icon. For instance:
* <ul>
* <li>input: <code>"bookmark"</code>, output: <code>"icon/bookmark.png"</code> (the file extension is
* included to support auto-detection of the MIME type without looking at the file contents)</li>
* <li>input: <code>"font:X"</code>, output: <code>"font:X"</code></li>
* </ul>
* The file extension is included to be able to auto-detect the MIME type based on it.
* <p>
* Use this method for image-files located in the /resource/icons directories of all jars on the classpath.
*/
public static String createIconUrl(String iconId) {
if (!StringUtility.hasText(iconId) || AbstractIcons.Null.equals(iconId)) {
return null;
}
if (iconId.startsWith("font:")) {
return iconId;
}
IconSpec iconSpec = IconLocator.instance().getIconSpec(iconId);
if (iconSpec != null) {
return "icon/" + iconSpec.getName(); // includes file extension
}
LOG.warn("iconId '{}' could not be resolved", iconId);
return iconId; // may happen, when no icon is available for the requested iconName
}
/**
* Helper method for {@link #ICON_REGEX_PATTERN} to replace all occurrences with the proper url.
*/
public static String replaceIconIdHandlerWithUrl(String str) {
if (str == null) {
return null;
}
Matcher m = ICON_REGEX_PATTERN.matcher(str);
@SuppressWarnings("squid:S1149")
StringBuffer ret = new StringBuffer();
while (m.find()) {
m.appendReplacement(ret, m.group(1) + createIconUrl(m.group(2)) + m.group(1));
}
m.appendTail(ret);
return ret.toString();
}
public static String createDynamicAdapterResourceUrl(IJsonAdapter<?> jsonAdapter, BinaryResource binaryResource) {
if (!checkDynamicAdapterResourceUrlArguments(jsonAdapter, binaryResource)) {
return null;
}
return new DynamicResourceInfo(jsonAdapter, getFilenameWithFingerprint(binaryResource)).toPath();
}
/**
* @return a relative URL for a resource handled by an adapter, see {@link DynamicResourceLoader}.
* <p>
* The calling adapter must implement {@link IBinaryResourceProvider}.
*/
public static String createDynamicAdapterResourceUrl(IJsonAdapter<?> jsonAdapter, String filename) {
if (!checkDynamicAdapterResourceUrlArguments(jsonAdapter, filename)) {
return null;
}
return new DynamicResourceInfo(jsonAdapter, filename).toPath();
}
/**
* @param jsonAdapter
* @param path
* decoded path (non URL encoded)
* @return
*/
public static String getFilenameWithFingerprint(IJsonAdapter<?> jsonAdapter, String path) {
if (!checkDynamicAdapterResourceUrlArguments(jsonAdapter, path)) {
return null;
}
DynamicResourceInfo info = DynamicResourceInfo.fromPath(jsonAdapter, path);
if (info == null) {
return null;
}
return info.getFileName();
}
public static String getFilenameWithFingerprint(BinaryResource binaryResource) {
return BinaryResourceUtility.createFilenameWithFingerprint(binaryResource);
}
private static boolean checkDynamicAdapterResourceUrlArguments(IJsonAdapter<?> jsonAdapter, Object arg) {
if (jsonAdapter == null) {
return false;
}
if (!(jsonAdapter instanceof IBinaryResourceProvider)) {
LOG.warn("adapter {} is not implementing {}", jsonAdapter, IBinaryResourceProvider.class.getName());
return false;
}
if (arg == null) {
return false;
}
return true;
}
/**
* Helper method for {@link #BINARY_RESOURCE_REGEX_PATTERN} to replace all occurrences with the proper URL.
*/
public static String replaceBinaryResourceHandlerWithUrl(IJsonAdapter<?> jsonAdapter, String str) {
if (str == null) {
return null;
}
Matcher m = BINARY_RESOURCE_REGEX_PATTERN.matcher(str);
@SuppressWarnings("squid:S1149")
StringBuffer ret = new StringBuffer();
while (m.find()) {
m.appendReplacement(ret, m.group(1) + createDynamicAdapterResourceUrl(jsonAdapter, m.group(2)) + m.group(1));
}
m.appendTail(ret);
return ret.toString();
}
/**
* Helper method to replace all common placeholders for images in the given string.
* <ol>
* <li>Icon IDs in the format: <code>iconId:star</code></li>
* <li>Binary resources in the format: <code>binaryResource:image</code></li>
* </ol>
*/
public static String replaceImageUrls(IJsonAdapter<?> jsonAdapter, String str) {
str = replaceIconIdHandlerWithUrl(str);
return replaceBinaryResourceHandlerWithUrl(jsonAdapter, str);
}
/**
* Provides a binary resource (holder) for the given filename, which may contain a fingerprint. The attachmentProvider
* is a callback to retrieve the right binary resource from the model.
*/
public static BinaryResourceHolder provideBinaryResource(String filenameWithFingerprint, Function<String, BinaryResource> attachmentProvider) {
Pair<String, Long> filenameAndFingerprint = BinaryResourceUtility.extractFilenameWithFingerprint(filenameWithFingerprint);
String filename = filenameAndFingerprint.getLeft();
BinaryResource attachment = attachmentProvider.apply(filename);
return attachment == null ? null : new BinaryResourceHolder(attachment);
}
}