/*
* Copyright (c) 2012, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
*
* 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.dart.tools.debug.core.server;
import com.google.dart.tools.debug.core.DartDebugCorePlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.sourcelookup.ISourceContainerType;
import org.eclipse.debug.core.sourcelookup.containers.AbstractSourceContainer;
import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
/**
* An ISourceContainer that searches in active debug connections and returns remote script objects.
*/
public class ServerRemoteScriptSourceContainer extends AbstractSourceContainer {
public static final String TYPE_ID = DebugPlugin.getUniqueIdentifier()
+ ".containerType.workspace"; //$NON-NLS-1$
private Map<String, LocalFileStorage> cachedSourceMap = new HashMap<String, LocalFileStorage>();
public ServerRemoteScriptSourceContainer() {
}
@Override
public Object[] findSourceElements(String name) throws CoreException {
if (name == null) {
return EMPTY;
}
if (name.startsWith("builtin:")) {
ServerDebugTarget target = ServerDebugTarget.getActiveTarget();
if (target != null) {
// builtin:id:url
name = name.substring("builtin:".length());
int index = name.indexOf(':');
String url = name.substring(index + 1);
int libraryId = Integer.parseInt(name.substring(0, index));
// TODO(devoncarew): change the buildin: format to an opaque token into a map; this will
// let us eliminate the call to target.getCurrentIsolate().
String source = target.getConnection().getScriptSource(
target.getCurrentIsolate(),
libraryId,
url);
if (source != null) {
try {
return new Object[] {getCreateStorageFor(url, source)};
} catch (IOException e) {
throw new CoreException(new Status(
IStatus.ERROR,
DartDebugCorePlugin.PLUGIN_ID,
e.toString(),
e));
}
}
}
}
return EMPTY;
}
@Override
public String getName() {
return "Remote Scripts";
}
@Override
public ISourceContainerType getType() {
return getSourceContainerType(TYPE_ID);
}
private LocalFileStorage getCreateStorageFor(String url, String source) throws IOException {
if (!cachedSourceMap.containsKey(url)) {
String fileName = url;
if (fileName.equals("bootstrap_impl")) {
fileName = "dart:" + fileName;
}
File file = File.createTempFile(sanitizeFileName(fileName) + "$$", ".dart");
file.deleteOnExit();
Writer out = new OutputStreamWriter(new FileOutputStream(file), Charset.forName("UTF8"));
out.write(source);
out.close();
file.setReadOnly();
LocalFileStorage fileStorage = new LocalFileStorage(file);
cachedSourceMap.put(url, fileStorage);
}
return cachedSourceMap.get(url);
}
private String sanitizeFileName(String str) {
return str.replace(':', '~').replace('/', '_').replace('\\', '_');
}
}