/* * Copyright (c) 2014, 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.pubserve; import com.google.dart.tools.core.DartCore; import com.google.dart.tools.debug.core.util.IResourceResolver; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * A resolver that calls out to pub serve for the information. */ public class PubServeResourceResolver implements IResourceResolver { private class FilePathForUrlCallback implements PubCallback<PubAsset> { private CountDownLatch latch; private String[] packageName; private String[] path; public FilePathForUrlCallback(CountDownLatch latch, String[] name, String[] path) { this.latch = latch; this.packageName = name; this.path = path; } @Override public void handleResult(PubResult<PubAsset> result) { if (result.isError()) { path[0] = null; } else { packageName[0] = result.getResult().getPackageStr(); path[0] = result.getResult().getPath(); } latch.countDown(); } } private class UrlForFileCallback implements PubCallback<String> { private CountDownLatch latch; private String[] done; public UrlForFileCallback(CountDownLatch latch, String[] done) { this.latch = latch; this.done = done; } @Override public void handleResult(PubResult<String> result) { if (result.isError()) { done[0] = null; } else { done[0] = result.getResult(); } latch.countDown(); } } private Map<String, String> urlToAsset = new HashMap<String, String>(); private Map<String, String> resourceToUrl = new HashMap<String, String>(); public PubServeResourceResolver() { } @Override public String getUrlForFile(File file) { IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(file.toURI()); if (files.length > 0) { return getUrlForResource(files[0]); } else { return null; } } @Override public String getUrlForResource(IResource resource) { String url = resourceToUrl.get(resource.getFullPath().toString()); if (url != null) { return url; } final String[] done = new String[1]; if (PubServeManager.getManager().isServing()) { CountDownLatch latch = new CountDownLatch(1); try { PubServeManager.getManager().sendGetUrlCommand( resource, new UrlForFileCallback(latch, done)); } catch (IOException e) { DartCore.logError(e); return done[0]; } try { latch.await(3000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { // do nothing } if (done[0] != null) { resourceToUrl.put(resource.getFullPath().toString(), done[0]); } } return done[0]; } @Override public String getUrlRegexForResource(IResource resource) { IContainer appDir = DartCore.getApplicationDirectory(resource); // remove till application directory // L/sample/web/sample.dart => web/sample.dart if (appDir != null) { String regex = resource.getProjectRelativePath().removeFirstSegments( appDir.getProjectRelativePath().segmentCount()).toPortableString(); // remove the pub serve root dir for the resource // web/sample.dart => sample.dart // http://127.0.0.1:8080/sample.html String rootdir = PubServeManager.getManager().getPubServeRootDir(appDir, resource); if (rootdir != null) { regex = regex.substring(rootdir.length()); } // for BreakpointManager to process the regex if (!regex.startsWith("/")) { regex = "/" + regex; } return regex; } return null; } @Override public IResource resolveUrl(String url) { String assetId = urlToAsset.get(url); if (assetId != null) { return getResourceForPath(assetId); } if (PubServeManager.getManager().isServing()) { CountDownLatch latch = new CountDownLatch(1); final String[] name = new String[1]; final String[] path = new String[1]; try { PubServeManager.getManager().sendGetAssetIdCommand( url, new FilePathForUrlCallback(latch, name, path)); } catch (IOException e) { DartCore.logError(e); return null; } try { latch.await(3000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { // do nothing } if (path[0] != null) { urlToAsset.put(url, path[0]); return getResourceForPath(path[0]); } } return null; } private IResource getResourceForPath(final String path) { IContainer appDir = PubServeManager.getManager().getCurrentServeWorkingDir(); // TODO(keertip): check if appdir has pubfolder with same pubspec name IResource resource = appDir.findMember(path); return resource; } }