| /* |
| * 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; |
| } |
| } |