blob: db2fe45e0af11d46ff797c58c7f6bb08e28a71d8 [file] [log] [blame]
/*
* Copyright 2015 Google Inc.
*
* 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.google.gwt.dev.codeserver;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.codeserver.Pages.ErrorPage;
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
/**
* Serves GWT symbol maps.
*/
class SymbolMapHandler {
/**
* The URL prefix for all symbol maps.
*/
static final String SYMBOLMAP_PATH = "/symbolmaps/";
/**
* The suffix that Super Dev Mode uses in symbol map URL's.
*/
private static final String SYMBOLMAP_URL_SUFFIX = ".symbolMap";
/**
* Matches a valid symbol map file request.
*/
private static final Pattern SYMBOLMAP_FILENAME_PATTERN = Pattern.compile(
"^(" + WebServer.STRONG_NAME + ")" + Pattern.quote(SYMBOLMAP_URL_SUFFIX) + "$");
/**
* Matches a valid symbol map request.
*/
private static final Pattern SYMBOLMAP_MODULE_PATTERN = Pattern.compile(
"^" + SYMBOLMAP_PATH + "([^/]+)/");
private final OutboxTable outboxTable;
SymbolMapHandler(OutboxTable outboxTable) {
this.outboxTable = outboxTable;
}
static boolean isSymbolMapRequest(String target) {
return getModuleNameFromRequest(target) != null;
}
Response handle(String target, HttpServletRequest request, TreeLogger logger) {
String moduleName = getModuleNameFromRequest(target);
if (moduleName == null) {
throw new RuntimeException("invalid request (shouldn't happen): " + target);
}
Outbox box = outboxTable.findByOutputModuleName(moduleName);
if (box == null) {
return new ErrorPage("No such module: " + moduleName);
} else if (box.containsStubCompile()) {
return new ErrorPage("This module hasn't been compiled yet.");
}
String rootDir = SYMBOLMAP_PATH + moduleName + "/";
String rest = target.substring(rootDir.length());
if (rest.isEmpty()) {
return new ErrorPage("Missing permutation id");
} else if (rest.endsWith("/")) {
return new ErrorPage("Can not list directory");
} else {
String strongName = getStrongNameFromSymbolmapFilename(rest);
if (strongName != null) {
File symbolMap = box.findSymbolMap(strongName).getAbsoluteFile();
return Responses.newFileResponse("text/plain", symbolMap);
} else {
return new ErrorPage("page not found");
}
}
}
private static String getModuleNameFromRequest(String target) {
Matcher matcher = SYMBOLMAP_MODULE_PATTERN.matcher(target);
return matcher.find() ? matcher.group(1) : null;
}
private static String getStrongNameFromSymbolmapFilename(String target) {
Matcher matcher = SYMBOLMAP_FILENAME_PATTERN.matcher(target);
return matcher.matches() ? matcher.group(1) : null;
}
}