ApplicationConfiguration.runWhenDependenciesLoaded(c);
}
- private static void loadStyleDependencies(JsArrayString dependencies) {
+ private void loadStyleDependencies(JsArrayString dependencies) {
// Assuming no reason to interpret in a defined order
ResourceLoadListener resourceLoadListener = new ResourceLoadListener() {
public void onLoad(ResourceLoadEvent event) {
};
ResourceLoader loader = ResourceLoader.get();
for (int i = 0; i < dependencies.length(); i++) {
+ String url = translateVaadinUri(dependencies.get(i));
ApplicationConfiguration.startDependencyLoading();
- loader.loadStylesheet(dependencies.get(i), resourceLoadListener);
+ loader.loadStylesheet(url, resourceLoadListener);
}
}
- private static void loadScriptDependencies(final JsArrayString dependencies) {
+ private void loadScriptDependencies(final JsArrayString dependencies) {
if (dependencies.length() == 0) {
return;
}
ResourceLoadListener resourceLoadListener = new ResourceLoadListener() {
public void onLoad(ResourceLoadEvent event) {
if (dependencies.length() != 0) {
+ String url = translateVaadinUri(dependencies.shift());
ApplicationConfiguration.startDependencyLoading();
// Load next in chain (hopefully already preloaded)
- event.getResourceLoader().loadScript(dependencies.shift(),
- this);
+ event.getResourceLoader().loadScript(url, this);
}
// Call start for next before calling end for current
ApplicationConfiguration.endDependencyLoading();
ResourceLoader loader = ResourceLoader.get();
// Start chain by loading first
+ String url = translateVaadinUri(dependencies.shift());
ApplicationConfiguration.startDependencyLoading();
- loader.loadScript(dependencies.shift(), resourceLoadListener);
+ loader.loadScript(url, resourceLoadListener);
// Preload all remaining
for (int i = 0; i < dependencies.length(); i++) {
}
if (uidlUri.startsWith("app://")) {
uidlUri = getAppUri() + uidlUri.substring(6);
+ } else if (uidlUri.startsWith("connector://")) {
+ uidlUri = getAppUri() + "APP/CONNECTOR/"
+ + uidlUri.substring("connector://".length());
}
return uidlUri;
}
static final String UPLOAD_URL_PREFIX = "APP/UPLOAD/";
+ static final String CONNECTOR_RESOURCE_PREFIX = "/APP/CONNECTOR/";
+
/**
* Called by the servlet container to indicate to a servlet that the servlet
* is being placed into service.
CommunicationManager applicationManager = webApplicationContext
.getApplicationManager(application, this);
+ if (requestType == RequestType.CONNECTOR_RESOURCE) {
+ String pathInfo = getRequestPathInfo(request);
+ String resourceName = pathInfo
+ .substring(CONNECTOR_RESOURCE_PREFIX.length());
+
+ final String mimetype = getServletContext().getMimeType(
+ resourceName);
+
+ applicationManager.serveConnectorResource(resourceName,
+ request, response, mimetype);
+ return;
+ }
+
/* Update browser information from the request */
webApplicationContext.getBrowser().updateRequestDetails(request);
}
protected enum RequestType {
- FILE_UPLOAD, BROWSER_DETAILS, UIDL, OTHER, STATIC_FILE, APPLICATION_RESOURCE;
+ FILE_UPLOAD, BROWSER_DETAILS, UIDL, OTHER, STATIC_FILE, APPLICATION_RESOURCE, CONNECTOR_RESOURCE;
}
protected RequestType getRequestType(HttpServletRequest request) {
if (isFileUploadRequest(request)) {
return RequestType.FILE_UPLOAD;
+ } else if (isConnectorResourceRequest(request)) {
+ return RequestType.CONNECTOR_RESOURCE;
} else if (isBrowserDetailsRequest(request)) {
return RequestType.BROWSER_DETAILS;
} else if (isUIDLRequest(request)) {
&& request.getParameter("browserDetails") != null;
}
+ private boolean isConnectorResourceRequest(HttpServletRequest request) {
+ String path = getRequestPathInfo(request);
+ if (path != null && path.startsWith(CONNECTOR_RESOURCE_PREFIX)) {
+ return true;
+ }
+ return false;
+ }
+
private boolean isApplicationRequest(HttpServletRequest request) {
String path = getRequestPathInfo(request);
if (path != null && path.startsWith("/APP/")) {
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.text.CharacterIterator;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.servlet.http.HttpServletResponse;
+
import com.vaadin.Application;
import com.vaadin.Application.SystemMessages;
import com.vaadin.RootRequiresMoreInformationException;
private Connector highlightedConnector;
+ private Map<String, Class<?>> connectoResourceContexts = new HashMap<String, Class<?>>();
+
/**
* TODO New constructor - document me!
*
for (Class<? extends ClientConnector> class1 : newConnectorTypes) {
JavaScript jsAnnotation = class1.getAnnotation(JavaScript.class);
if (jsAnnotation != null) {
- scriptDependencies.addAll(Arrays.asList(jsAnnotation.value()));
+ for (String resource : jsAnnotation.value()) {
+ scriptDependencies.add(registerResource(resource, class1));
+ }
}
StyleSheet styleAnnotation = class1.getAnnotation(StyleSheet.class);
if (styleAnnotation != null) {
- styleDependencies
- .addAll(Arrays.asList(styleAnnotation.value()));
+ for (String resource : styleAnnotation.value()) {
+ styleDependencies.add(registerResource(resource, class1));
+ }
}
}
writePerformanceData(outWriter);
}
+ private String registerResource(String resource, Class<?> context) {
+ try {
+ URI uri = new URI(resource);
+ String protocol = uri.getScheme();
+
+ if ("connector".equals(protocol)) {
+ return registerContextResource(uri, context);
+ }
+
+ if (protocol != null || uri.getHost() != null) {
+ return resource;
+ }
+
+ String path = uri.getPath();
+ if (path.startsWith("/")) {
+ return resource;
+ }
+
+ // Default if just simple relative url
+ return registerContextResource(uri, context);
+ } catch (URISyntaxException e) {
+ getLogger().log(Level.WARNING,
+ "Could not parse resource url " + resource, e);
+ return resource;
+ }
+ }
+
+ private String registerContextResource(URI uri, Class<?> context) {
+ String path = uri.getPath();
+ synchronized (connectoResourceContexts) {
+ // Connector resource
+ if (connectoResourceContexts.containsKey(path)) {
+ Class<?> oldContext = connectoResourceContexts.get(path);
+ getLogger().warning(
+ "Resource " + path + " defined by both " + context
+ + " and " + oldContext + ". Resource from "
+ + oldContext + " will be used.");
+ } else {
+ connectoResourceContexts.put(path, context);
+ }
+ }
+
+ return "connector://" + path;
+ }
+
/**
* Adds the performance timing data (used by TestBench 3) to the UIDL
* response.
return initialUIDL;
}
+ public void serveConnectorResource(String resourceName,
+ WrappedRequest request, WrappedResponse response, String mimetype)
+ throws IOException {
+ if (resourceName.startsWith("/")) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, resourceName);
+ return;
+ }
+
+ Class<?> context;
+ synchronized (connectoResourceContexts) {
+ context = connectoResourceContexts.get(resourceName);
+ }
+
+ if (context == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, resourceName);
+ return;
+ }
+
+ InputStream in = context.getResourceAsStream(resourceName);
+ if (in == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, resourceName);
+ return;
+ }
+ OutputStream out = null;
+ try {
+ if (mimetype != null) {
+ response.setContentType(mimetype);
+ }
+
+ out = response.getOutputStream();
+
+ final byte[] buffer = new byte[Constants.DEFAULT_BUFFER_SIZE];
+
+ int bytesRead = 0;
+ while ((bytesRead = in.read(buffer)) > 0) {
+ out.write(buffer, 0, bytesRead);
+ }
+ out.flush();
+ } finally {
+ try {
+ in.close();
+ } catch (Exception e) {
+ // Do nothing
+ }
+ if (out != null) {
+ try {
+ out.close();
+ } catch (Exception e) {
+ // Do nothing
+ }
+ }
+ }
+ }
+
/**
* Stream that extracts content from another stream until the boundary
* string is encountered.