blob: 16e4d7afd1ebe4c3214bd9e1bee158aee14f096f [file] [log] [blame]
/*
* Copyright (c) 2013, 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.core.pub;
import com.google.dart.tools.core.DartCore;
import com.google.dart.tools.core.utilities.yaml.PubYamlUtils;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Maintains a list of the latest versions for all packages installed in the local pub cache.
*
* @coverage dart.tools.core.pub
*/
public class PubCacheManager_OLD {
protected class FillPubCacheList extends Job {
// Map of <packageName, version no> for packages added
Map<String, String> packages = null;
public FillPubCacheList(String name, Map<String, String> packages) {
super(name);
this.packages = packages;
}
@Override
public IStatus run(IProgressMonitor monitor) {
HashMap<String, Object> object = readPackageInfo();
if (object != null) {
synchronized (pubUsedPackages) {
pubCachePackages = object;
}
if (packages == null) {
initializeList();
if (!pubUsedPackages.isEmpty()) {
PubManager.getInstance().notifyListeners(getLocalPackages());
}
} else {
Map<String, Object> added = processPackages(packages);
if (!added.isEmpty()) {
PubManager.getInstance().notifyListeners(added);
}
}
}
return Status.OK_STATUS;
}
}
/**
* A map to store the list of the installed packages and their locations, synchronize on
* pubUsedPackages
*/
// {action_consolidator=
// {0.1.3=
// {location=/Users/keertip/.pub-cache/hosted/pub.dartlang.org/action_consolidator-0.1.3}},..
// }
protected HashMap<String, Object> pubCachePackages = new HashMap<String, Object>();
/**
* A map of packages & locations used in the open folders in the editor, access should be
* synchronized against itself
*/
protected final HashMap<String, Object> pubUsedPackages = new HashMap<String, Object>();
private static final PubCacheManager_OLD INSTANCE = new PubCacheManager_OLD();
public static final PubCacheManager_OLD getInstance() {
return INSTANCE;
}
// keeps track of packages last updated
private Map<String, String> currentPackages;
/**
* Return information about all the cached packages
*/
public HashMap<String, Object> getAllCachePackages() {
synchronized (pubUsedPackages) {
HashMap<String, Object> copy = new HashMap<String, Object>(pubCachePackages);
return copy;
}
}
/**
* Look in the pub cache list and return the location of package-version or {@code null} if not
* found
*
* @param packageName
* @param version
*/
@SuppressWarnings("unchecked")
public String getCacheLocation(String packageName, String version) {
HashMap<String, Object> map;
synchronized (pubUsedPackages) {
map = (HashMap<String, Object>) pubCachePackages.get(packageName);
}
if (map != null && map.keySet().contains(version)) {
return ((Map<String, String>) map.get(version)).get(PubspecConstants.LOCATION);
}
return null;
}
/**
* Return information about all the packages currently being used in all open folders
*/
public HashMap<String, Object> getLocalPackages() {
synchronized (pubUsedPackages) {
HashMap<String, Object> copy = new HashMap<String, Object>(pubUsedPackages);
return copy;
}
}
/**
* Run pub cache list and get the latest information about all cached packages.
*/
public HashMap<String, Object> updateAndGetAllCachePackages() {
HashMap<String, Object> map = readPackageInfo();
if (map != null) {
synchronized (pubUsedPackages) {
pubCachePackages = map;
}
}
return getAllCachePackages();
}
public void updatePackagesList(int delay) {
updatePackagesList(delay, null);
}
public void updatePackagesList(int delay, Map<String, String> packages) {
if (currentPackages == null || !currentPackages.equals(packages)) {
currentPackages = packages;
new FillPubCacheList("update installed packages", packages).schedule(delay);
}
}
protected IProject[] getProjects() {
try {
return ResourcesPlugin.getWorkspace().getRoot().getProjects();
} catch (IllegalStateException e) {
// The workspace is shutting down so return an empty list
return new IProject[] {};
}
}
protected String getPubCacheList() {
RunPubCacheListJob job = new RunPubCacheListJob();
return job.run(new NullProgressMonitor()).getMessage();
}
protected void processLockFileContents(IResource resource) {
// Map<packageName,versionNo>
Map<String, String> versionMap = PubYamlUtils.getPackageVersionMap(resource);
if (versionMap != null && !versionMap.isEmpty()) {
synchronized (pubUsedPackages) {
for (String packageName : versionMap.keySet()) {
String version = versionMap.get(packageName);
Map<String, String> versionInfo = getVersionInfo(packageName, version);
if (versionInfo != null) {
versionInfo.put(PubspecConstants.VERSION, version);
pubUsedPackages.put(packageName, versionInfo);
}
}
}
}
}
protected Map<String, Object> processPackages(Map<String, String> packages) {
// Map<packageName, {{"version",versionNo}{"location",locationPath}}>
Map<String, Object> added = new HashMap<String, Object>();
synchronized (pubUsedPackages) {
Set<String> usedKeySet = pubUsedPackages.keySet();
for (String packageName : packages.keySet()) {
String version = packages.get(packageName);
if (!usedKeySet.contains(packageName)) {
changeUsedPackage(added, packageName, version);
}
if (usedKeySet.contains(packageName)) {
if (!getUsedVersion(packageName).equals(version)) {
changeUsedPackage(added, packageName, version);
}
}
}
}
return added;
}
private void changeUsedPackage(Map<String, Object> added, String packageName, String version) {
Map<String, String> versionInfo = getVersionInfo(packageName, version);
if (versionInfo != null) {
versionInfo.put(PubspecConstants.VERSION, version);
pubUsedPackages.put(packageName, versionInfo);
added.put(packageName, versionInfo);
}
}
@SuppressWarnings("unchecked")
private String getUsedVersion(String packageName) {
Map<String, String> object;
synchronized (pubUsedPackages) {
object = (Map<String, String>) pubUsedPackages.get(packageName);
}
if (object != null) {
return object.get(PubspecConstants.VERSION);
}
return "";
}
/**
* Checks for the location information in the pub cache information for the given package and
* version
*
* @param packageName - the name of the pub package
* @param version - the version no of the package
* @return Map<"location",locationPath> for the package-version
*/
@SuppressWarnings("unchecked")
private Map<String, String> getVersionInfo(String packageName, String version) {
Map<String, Map<String, String>> object;
synchronized (pubUsedPackages) {
object = (Map<String, Map<String, String>>) pubCachePackages.get(packageName);
}
if (object != null) {
Map<String, String> versionInfo = object.get(version);
return versionInfo;
}
return null;
}
private void initializeList() {
IProject[] projects = getProjects();
for (IProject project : projects) {
try {
project.accept(new IResourceVisitor() {
@Override
public boolean visit(IResource resource) throws CoreException {
if (resource.getType() != IResource.FILE) {
return true;
}
if (resource.getName().equals(DartCore.PUBSPEC_LOCK_FILE_NAME)) {
processLockFileContents(resource);
}
return false;
}
});
} catch (CoreException e) {
// do nothing
}
}
}
@SuppressWarnings("unchecked")
private HashMap<String, Object> readPackageInfo() {
String message = getPubCacheList();
// no errors
if (message.startsWith("{\"packages")) {
Map<String, Object> object = null;
try {
object = PubYamlUtils.parsePubspecYamlToMap(message);
} catch (Exception e) {
DartCore.logError("Error while parsing pub cache list", e);
}
return (HashMap<String, Object>) object.get(PubspecConstants.PACKAGES);
} else {
DartCore.logError(message);
}
return null;
}
}