/* * Copyright 2000-2016 Vaadin Ltd. * * 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.vaadin.shared; import java.io.Serializable; import com.vaadin.shared.util.SharedUtil; /** * Utility for translating special Vaadin URIs like theme:// and app:// into * URLs usable by the browser. This is an abstract class performing the main * logic in {@link #resolveVaadinUri(String)} and using abstract methods in the * class for accessing information specific to the current environment. * * @since 7.4 * @author Vaadin Ltd */ public abstract class VaadinUriResolver implements Serializable { /** * Translates a Vaadin URI to a URL that can be loaded by the browser. The * following URI schemes are supported: * <ul> * <li><code>theme://</code> - resolves to the URL of the currently active * theme.</li> * <li><code>published://</code> - resolves to resources on the classpath * published by {@link com.vaadin.annotations.JavaScript @JavaScript} or * {@link com.vaadin.annotations.StyleSheet @StyleSheet} annotations on * connectors.</li> * <li><code>app://</code> - resolves to a URL that will be routed to the * currently registered {@link com.vaadin.server.RequestHandler * RequestHandler} instances.</li> * <li><code>vaadin://</code> - resolves to the location of static resouces * in the VAADIN directory</li> * <li><code>frontend://</code> - resolves to the location of frontend * (Bower and similar) resources, which might vary depending on the used * browser</li> * </ul> * Any other URI protocols, such as <code>http://</code> or * <code>https://</code> are passed through this method unmodified. * * @since 7.4 * @param vaadinUri * the uri to resolve * @return the resolved uri */ public String resolveVaadinUri(String vaadinUri) { if (vaadinUri == null) { return null; } if (vaadinUri .startsWith(ApplicationConstants.FRONTEND_PROTOCOL_PREFIX)) { final String frontendUrl = getFrontendUrl(); vaadinUri = frontendUrl + vaadinUri.substring( ApplicationConstants.FRONTEND_PROTOCOL_PREFIX.length()); } if (vaadinUri.startsWith(ApplicationConstants.THEME_PROTOCOL_PREFIX)) { final String themeUri = getThemeUri(); vaadinUri = themeUri + vaadinUri.substring(7); } if (vaadinUri .startsWith(ApplicationConstants.PUBLISHED_PROTOCOL_PREFIX)) { // getAppUri *should* always end with / // substring *should* always start with / (published:///foo.bar // without published://) vaadinUri = ApplicationConstants.APP_PROTOCOL_PREFIX + ApplicationConstants.PUBLISHED_FILE_PATH + vaadinUri.substring( ApplicationConstants.PUBLISHED_PROTOCOL_PREFIX .length()); // Let translation of app:// urls take care of the rest } if (vaadinUri.startsWith(ApplicationConstants.APP_PROTOCOL_PREFIX)) { String relativeUrl = vaadinUri.substring( ApplicationConstants.APP_PROTOCOL_PREFIX.length()); String serviceUrl = getServiceUrl(); String serviceUrlParameterName = getServiceUrlParameterName(); if (serviceUrlParameterName != null) { // Should put path in v-resourcePath parameter and append query // params to base portlet url String[] parts = relativeUrl.split("\\?", 2); String path = parts[0]; // If there's a "?" followed by something, append it as a query // string to the base URL if (parts.length > 1) { String appUrlParams = parts[1]; serviceUrl = SharedUtil.addGetParameters(serviceUrl, appUrlParams); } if (!path.startsWith("/")) { path = '/' + path; } String pathParam = serviceUrlParameterName + "=" + encodeQueryStringParameterValue(path); serviceUrl = SharedUtil.addGetParameters(serviceUrl, pathParam); vaadinUri = serviceUrl; } else { vaadinUri = serviceUrl + relativeUrl; } } if (vaadinUri.startsWith(ApplicationConstants.VAADIN_PROTOCOL_PREFIX)) { final String vaadinDirUri = getVaadinDirUrl(); String relativeUrl = vaadinUri.substring( ApplicationConstants.VAADIN_PROTOCOL_PREFIX.length()); vaadinUri = vaadinDirUri + relativeUrl; } if (vaadinUri .startsWith(ApplicationConstants.CONTEXT_PROTOCOL_PREFIX)) { final String contextRoot = getContextRootUrl(); String relativeUrl = vaadinUri.substring( ApplicationConstants.CONTEXT_PROTOCOL_PREFIX.length()); vaadinUri = contextRoot + relativeUrl; } return vaadinUri; } /** * Gets the URL pointing to the VAADIN directory. * * @return the VAADIN directory URL */ protected abstract String getVaadinDirUrl(); /** * Gets the name of the request parameter that should be used for sending * the requested URL to the {@link #getServiceUrl() service URL}. If * <code>null</code> is returned, the requested URL will instead be appended * to the base service URL. * * @return the parameter name used for passing request URLs, or * <code>null</code> to send the path as a part of the request path. */ protected abstract String getServiceUrlParameterName(); /** * Gets the URL handled by {@link com.vaadin.server.VaadinService * VaadinService} to handle application requests. * * @return the service URL */ protected abstract String getServiceUrl(); /** * Gets the URL pointing to the context root. * * @return the context root URL * * @since 8.0.3 */ protected abstract String getContextRootUrl(); /** * Gets the URI of the directory of the current theme. * * @return the URI of the current theme directory */ protected abstract String getThemeUri(); /** * Encodes a value for safe inclusion as a parameter in the query string. * * @param parameterValue * the value to encode * @return the encoded value */ protected abstract String encodeQueryStringParameterValue( String parameterValue); /** * Returns the URL pointing to the folder containing frontend files, either * for ES5 (if browser does not support ES6) or ES6 (most browsers). * * @return the absolute or relative URL to the frontend files, ending with a * slash '/' * @since 8.1 */ protected abstract String getFrontendUrl(); }