// Copyright 2012 Google Inc. All Rights Reserved.
//
// 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.collide.client.code.debugging;
import com.google.collide.client.code.debugging.DebuggerApiTypes.BreakpointInfo;
import com.google.collide.client.code.debugging.DebuggerApiTypes.Location;
import com.google.collide.client.code.debugging.DebuggerApiTypes.OnScriptParsedResponse;
import com.google.collide.client.util.PathUtil;
import com.google.collide.shared.util.RegExpUtils;
import com.google.common.base.Preconditions;
import javax.annotation.Nullable;
/**
* Identity source mapping to be used for static files.
*
*/
class StaticSourceMapping implements SourceMapping {
private final String resourceBaseUri;
static StaticSourceMapping create(String baseUri) {
Preconditions.checkNotNull(baseUri, "Base URI is NULL!");
return new StaticSourceMapping(baseUri);
}
private StaticSourceMapping(String resourceBaseUri) {
this.resourceBaseUri = ensureNoTrailingSlash(resourceBaseUri).toLowerCase();
}
@Override
public PathUtil getLocalScriptPath(@Nullable OnScriptParsedResponse response) {
if (response == null) {
return null;
}
return getLocalSourcePath(response.getUrl());
}
@Override
public int getLocalSourceLineNumber(@Nullable OnScriptParsedResponse response,
Location location) {
return location.getLineNumber();
}
@Override
public BreakpointInfo getRemoteBreakpoint(Breakpoint breakpoint) {
String url = getRemoteSourceUri(breakpoint.getPath());
// We allow arbitrary query and anchor parts in the breakpoint URLs for
// static resources.
String urlRegex = "^" + RegExpUtils.escape(url) + "([?#].*)?$";
return new BreakpointInfoImpl(urlRegex,
breakpoint.getLineNumber(), 0, breakpoint.getCondition());
}
@Override
public PathUtil getLocalSourcePath(String resourceUri) {
Preconditions.checkNotNull(resourceBaseUri, "Base URI is NULL! Impossible?!");
// TODO: stopgap to get more
// stable build to rehearse his demo with. Suggest tracking down actual
// source of why resourceBaseUri could be null.
if (resourceUri == null || resourceBaseUri == null) {
return null;
}
if (resourceUri.toLowerCase().startsWith(resourceBaseUri)) {
String relativePath = resourceUri.substring(resourceBaseUri.length());
// We drop any query and anchor part, since we assume this is a static
// resource.
int pos = relativePath.indexOf('?');
if (pos != -1) {
relativePath = relativePath.substring(0, pos);
}
pos = relativePath.indexOf('#');
if (pos != -1) {
relativePath = relativePath.substring(0, pos);
}
return new PathUtil(relativePath);
}
return null;
}
@Override
public String getRemoteSourceUri(PathUtil path) {
return resourceBaseUri + path.getPathString();
}
private static String ensureNoTrailingSlash(String path) {
while (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
return path;
}
private static class BreakpointInfoImpl implements BreakpointInfo {
private final String urlRegex;
private final int lineNumber;
private final int columnNumber;
private final String condition;
private BreakpointInfoImpl(
String urlRegex, int lineNumber, int columnNumber, String condition) {
this.urlRegex = urlRegex;
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
this.condition = condition;
}
@Override
public String getUrl() {
return null; // urlRegex will be used instead.
}
@Override
public String getUrlRegex() {
return urlRegex;
}
@Override
public int getLineNumber() {
return lineNumber;
}
@Override
public int getColumnNumber() {
return columnNumber;
}
@Override
public String getCondition() {
return condition;
}
}
}