/** * Copyright (c) 2005-2013 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ /* * Created on Sep 13, 2005 * * @author Fabio Zadrozny */ package com.python.pydev.analysis.additionalinfo; import java.io.File; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.python.pydev.core.IInterpreterInfo; import org.python.pydev.core.IInterpreterManager; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.ISystemModulesManager; import org.python.pydev.core.MisconfigurationException; import org.python.pydev.core.docutils.PyStringUtils; import org.python.pydev.core.log.Log; import org.python.pydev.plugin.nature.SystemPythonNature; import org.python.pydev.shared_core.structure.Tuple; import org.python.pydev.ui.interpreters.PythonInterpreterManager; import org.python.pydev.ui.pythonpathconf.InterpreterInfo; import com.python.pydev.analysis.AnalysisPlugin; public class AdditionalSystemInterpreterInfo extends AbstractAdditionalInfoWithBuild { private final IInterpreterManager manager; private final String additionalInfoInterpreter; /** * holds system info (interpreter name points to system info) */ private final static Map<Tuple<String, String>, AbstractAdditionalTokensInfo> additionalSystemInfo = new HashMap<Tuple<String, String>, AbstractAdditionalTokensInfo>(); private final static Object additionalSystemInfoLock = new Object(); private final File persistingFolder; private final File persistingLocation; private IPythonNature nature; public IInterpreterManager getManager() { return manager; } public String getAdditionalInfoInterpreter() { return additionalInfoInterpreter; } @Override protected String getUIRepresentation() { return manager != null ? manager.getManagerRelatedName() : "Unknown manager"; } @Override protected IPythonNature getNature() { return nature; } /** * @return the path to the folder we want to keep things on * @throws MisconfigurationException */ @Override protected File getPersistingFolder() { return persistingFolder; } @Override protected File getPersistingLocation() throws MisconfigurationException { return persistingLocation; } @Override protected Set<String> getPythonPathFolders() { Set<String> ret = new HashSet<>(); try { IInterpreterInfo interpreterInfo = this.manager.getInterpreterInfo(additionalInfoInterpreter, new NullProgressMonitor()); ret.addAll(interpreterInfo.getPythonPath()); } catch (MisconfigurationException e) { Log.log(e); } return ret; } public AdditionalSystemInterpreterInfo(IInterpreterManager manager, String interpreter) throws MisconfigurationException { super(false); //don't call init just right now... this.manager = manager; this.additionalInfoInterpreter = interpreter; try { nature = manager != null ? new SystemPythonNature(manager) : null; } catch (MisconfigurationException e) { Log.log(e); } File base; try { IPath stateLocation = AnalysisPlugin.getDefault().getStateLocation(); base = stateLocation.toFile(); } catch (Exception e) { //it may fail in tests... (save it in default folder in this cases) Log.logInfo("Error getting persisting folder", e); base = new File("."); } File file = new File(base, manager.getManagerRelatedName() + "_" + PyStringUtils.getExeAsFileSystemValidPath(this.additionalInfoInterpreter)); try { if (!file.exists()) { file.mkdirs(); } } catch (Exception e) { Log.log(e); } persistingFolder = file; persistingLocation = new File(persistingFolder, manager.getManagerRelatedName() + ".pydevsysteminfo"); init(); } public static AbstractAdditionalDependencyInfo getAdditionalSystemInfo(IInterpreterManager manager, String interpreter) throws MisconfigurationException { return getAdditionalSystemInfo(manager, interpreter, false); } /** * Should only be used in tests. */ public static void setAdditionalSystemInfo(PythonInterpreterManager manager, String executableOrJar, AdditionalSystemInterpreterInfo additionalInfo) { synchronized (additionalSystemInfoLock) { Tuple<String, String> key = new Tuple<String, String>(manager.getManagerRelatedName(), executableOrJar); additionalSystemInfo.put(key, additionalInfo); } } /** * @param m the module manager that we want to get info on (python, jython...) * @return the additional info for the system * @throws MisconfigurationException */ public static AbstractAdditionalDependencyInfo getAdditionalSystemInfo(IInterpreterManager manager, String interpreter, boolean errorIfNotAvailable) throws MisconfigurationException { Tuple<String, String> key = new Tuple<String, String>(manager.getManagerRelatedName(), interpreter); synchronized (additionalSystemInfoLock) { AbstractAdditionalDependencyInfo info = (AbstractAdditionalDependencyInfo) additionalSystemInfo.get(key); if (info == null) { //lazy-load. info = new AdditionalSystemInterpreterInfo(manager, interpreter); additionalSystemInfo.put(key, info); if (!info.load()) { try { recreateAllInfo(manager, interpreter, new NullProgressMonitor()); info = (AbstractAdditionalDependencyInfo) additionalSystemInfo.get(key); } catch (Exception e) { Log.log(e); } } } return info; } } public static void recreateAllInfo(IInterpreterManager manager, String interpreter, IProgressMonitor monitor) { synchronized (additionalSystemInfoLock) { try { final IInterpreterInfo interpreterInfo = manager.getInterpreterInfo(interpreter, monitor); int grammarVersion = interpreterInfo.getGrammarVersion(); AbstractAdditionalTokensInfo currInfo = AdditionalSystemInterpreterInfo.getAdditionalSystemInfo( manager, interpreter); if (currInfo != null) { currInfo.clearAllInfo(); } InterpreterInfo defaultInterpreterInfo = (InterpreterInfo) manager.getInterpreterInfo(interpreter, monitor); ISystemModulesManager m = defaultInterpreterInfo.getModulesManager(); AbstractAdditionalTokensInfo info = restoreInfoForModuleManager(monitor, m, "(system: " + manager.getManagerRelatedName() + " - " + interpreter + ")", new AdditionalSystemInterpreterInfo(manager, interpreter), null, grammarVersion); if (info != null) { //ok, set it and save it additionalSystemInfo.put(new Tuple<String, String>(manager.getManagerRelatedName(), interpreter), info); info.save(); } } catch (Throwable e) { Log.log(e); } } } //Make it available for being in a HashSet. @Override public int hashCode() { return this.additionalInfoInterpreter.hashCode(); } @Override public boolean equals(Object obj) { if (!(obj instanceof AdditionalSystemInterpreterInfo)) { return false; } AdditionalSystemInterpreterInfo additionalSystemInterpreterInfo = (AdditionalSystemInterpreterInfo) obj; return this.additionalInfoInterpreter.equals(additionalSystemInterpreterInfo.additionalInfoInterpreter); } }