| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| package com.google.dart.compiler; |
| |
| import com.google.dart.compiler.SystemLibrariesReader.DartLibrary; |
| |
| import java.io.File; |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| |
| /** |
| * A Library manager that manages system libraries |
| */ |
| public class SystemLibraryManager { |
| |
| private HashMap<String, String> expansionMap; |
| private Map<String, SystemLibrary> hostMap; |
| private final URI sdkLibPathUri; |
| |
| private Map<URI, URI> longToShortUriMap; |
| |
| private List<SystemLibrary> libraries; |
| private final SystemLibraryProvider libraryProvider; |
| |
| public SystemLibraryManager(File sdkPath) { |
| this(new FileBasedSystemLibraryProvider(sdkPath)); |
| } |
| |
| public SystemLibraryManager(SystemLibraryProvider libraryProvider) { |
| this.libraryProvider = libraryProvider; |
| this.sdkLibPathUri = libraryProvider.getSdkLibPathUri(); |
| setLibraries(getDefaultLibraries()); |
| } |
| |
| public URI expandRelativeDartUri(URI uri) throws AssertionError { |
| String host = uri.getHost(); |
| if (host == null) { |
| String spec = uri.getSchemeSpecificPart(); |
| String replacement = expansionMap.get(spec); |
| if (replacement != null) { |
| try { |
| uri = new URI(PackageLibraryManager.DART_SCHEME + ":" + replacement); |
| } catch (URISyntaxException e) { |
| throw new AssertionError(); |
| } |
| } else { |
| return null; |
| } |
| } |
| return uri; |
| } |
| |
| public URI getRelativeUri(URI fileUri) { |
| |
| if (fileUri == null || !fileUri.getScheme().equals("file")){ |
| return null; |
| } |
| |
| URI relativeUri = sdkLibPathUri.relativize(fileUri); |
| if (relativeUri.getScheme() == null) { |
| try { |
| return new URI(null, null, "dart://" + relativeUri.getPath(), null, null); |
| } catch (URISyntaxException e) { |
| //$FALL-THROUGH$ |
| } |
| } |
| return null; |
| } |
| |
| public URI getShortUri(URI uri) { |
| URI shortUri = longToShortUriMap.get(uri); |
| if (shortUri != null){ |
| return shortUri; |
| } |
| shortUri = getRelativeUri(uri); |
| if (shortUri != null){ |
| try { |
| return new URI(null, null, shortUri.getScheme() + ":" + shortUri.getHost() + shortUri.getPath(),null, null); |
| } catch (URISyntaxException e) { |
| } |
| } |
| return null; |
| } |
| |
| public URI translateDartUri(URI uri) { |
| |
| String host = uri.getHost(); |
| SystemLibrary library = hostMap.get(host); |
| if (library != null) { |
| return library.translateUri(uri); |
| } |
| if (host != null) { |
| return libraryProvider.resolveHost(host, uri); |
| } |
| throw new RuntimeException("No system library defined for " + uri); |
| |
| } |
| |
| |
| public Collection<String> getAllLibrarySpecs() { |
| Collection<String> result = new ArrayList<String>(libraries.size()); |
| for (SystemLibrary lib : libraries) { |
| result.add("dart:" + lib.getShortName()); |
| } |
| return result; |
| } |
| |
| public Collection<SystemLibrary> getAllSystemLibraries(){ |
| return libraries; |
| } |
| |
| /** |
| * Load the libraries listed out in the libraries.dart files as read by the {@link SystemLibrariesReader} |
| */ |
| protected SystemLibrary[] getDefaultLibraries() { |
| libraries = new ArrayList<SystemLibrary>(); |
| longToShortUriMap = new HashMap<URI, URI>(); |
| |
| // Cycle through the import.config, extracting explicit mappings and searching directories |
| URI base = this.sdkLibPathUri; |
| |
| Map<String, DartLibrary> declaredLibraries = libraryProvider.getLibraryMap(); |
| |
| HashSet<String> explicitShortNames = new HashSet<String>(); |
| |
| for (Entry<String, DartLibrary> entry : declaredLibraries.entrySet()) { |
| if (entry.getValue().getCategory().equals("Internal")){ |
| continue; |
| } |
| String shortName = entry.getKey().trim(); |
| DartLibrary library = entry.getValue(); |
| String path = library.getPath(); |
| URI libFileUri; |
| try { |
| libFileUri = base.resolve(new URI(null, null, path, null, null)).normalize(); |
| } catch (URISyntaxException e) { |
| continue; |
| } |
| |
| if (!libraryProvider.exists(libFileUri)) { |
| throw new InternalCompilerException("Can't find system library dart:" + shortName |
| + " at " + libFileUri); |
| } |
| |
| int index = shortName.indexOf(':'); |
| if (index == -1) { |
| continue; |
| } |
| explicitShortNames.add(shortName); |
| String scheme = shortName.substring(0, index + 1); |
| String name = shortName.substring(index + 1); |
| |
| String relPath = sdkLibPathUri.relativize(libFileUri).getPath(); |
| index = relPath.indexOf('/'); |
| if (index == -1) { |
| continue; |
| } |
| String host = relPath.substring(0, index); |
| String pathToLib = relPath.substring(index + 1); |
| |
| addLib(scheme, |
| host, |
| name, |
| pathToLib, |
| library.getCategory(), |
| library.isDocumented(), |
| library.isImplementation()); |
| |
| } |
| return libraries.toArray(new SystemLibrary[libraries.size()]); |
| } |
| |
| protected boolean addLib(String scheme, String host, String name, String pathToLib, |
| String category, boolean documented, boolean implementation) |
| throws AssertionError { |
| |
| SystemLibrary lib = libraryProvider.createSystemLibrary(name, host, pathToLib, category, documented, implementation); |
| libraries.add(lib); |
| |
| String libSpec = scheme + name; |
| URI libUri; |
| URI expandedUri; |
| try { |
| libUri = new URI(libSpec); |
| expandedUri = new URI("dart:" + "//" + host + "/" + pathToLib); |
| } catch (URISyntaxException e) { |
| throw new AssertionError(e); |
| } |
| URI resolvedUri = lib.translateUri(expandedUri); |
| longToShortUriMap.put(resolvedUri, libUri); |
| longToShortUriMap.put(expandedUri, libUri); |
| return true; |
| } |
| |
| /** |
| * Register system libraries for the "dart:" protocol such that dart:[shortLibName] (e.g. |
| * "dart:html") will automatically be expanded to dart://[host]/[pathToLib] (e.g. |
| * dart://html/html.dart) |
| */ |
| private void setLibraries(SystemLibrary[] newLibraries) { |
| libraries = new ArrayList<SystemLibrary>(); |
| hostMap = new HashMap<String, SystemLibrary>(); |
| expansionMap = new HashMap<String, String>(); |
| for (SystemLibrary library : newLibraries) { |
| String host = library.getHost(); |
| SystemLibrary existingLib = hostMap.get(host); |
| if (existingLib != null) { |
| libraries.remove(existingLib); |
| } |
| libraries.add(library); |
| hostMap.put(host, library); |
| expansionMap.put(library.getShortName(), |
| "//" + host + "/" + library.getPathToLib()); |
| } |
| } |
| |
| /** |
| * Check if this URI denotes a patch file. |
| */ |
| public boolean isPatchFile(URI uri) { |
| return libraryProvider.isPatchFile(uri); |
| } |
| |
| } |