package com.intellij.perlplugin; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.perlplugin.bo.Package; import com.intellij.perlplugin.bo.PendingPackage; import com.intellij.perlplugin.bo.Sub; import com.intellij.perlplugin.extensions.PerlCompletionContributor; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; /** * Created by eli on 27-11-14. */ public class ModulesContainer { public static float totalDelays = 0; private static boolean initialized = false; private static HashMap<String, ArrayList<Package>> packageNamesToPackages = new HashMap<String, ArrayList<Package>>(); private static HashMap<String, HashSet<Sub>> subNamesToSubs = new HashMap<String, HashSet<Sub>>(); private static HashMap<String, ArrayList<Package>> filePathsToPackages = new HashMap<String, ArrayList<Package>>(); private static HashMap<String, HashSet<String>> parentsToChildrenPackageNames = new HashMap<String, HashSet<String>>(); private static ArrayList<PendingPackage> pendingParentPackages = new ArrayList<PendingPackage>(); private static ArrayList<String> problematicFiles = new ArrayList<String>(); //PACKAGES public static void addPackage(Package packageObj) { if (!packageNamesToPackages.containsKey(packageObj.getQualifiedName())) { packageNamesToPackages.put(packageObj.getQualifiedName(), new ArrayList<Package>()); } packageNamesToPackages.get(packageObj.getQualifiedName()).add(packageObj); if (!filePathsToPackages.containsKey(packageObj.getOriginFile())) { filePathsToPackages.put(packageObj.getOriginFile(), new ArrayList<Package>()); } filePathsToPackages.get(packageObj.getOriginFile()).add(packageObj); } public static ArrayList<Package> getPackageList(String packageName) { ArrayList<Package> packageList = new ArrayList<Package>(); for (String key : packageNamesToPackages.keySet()) { if (key.equals(packageName)) { packageList.addAll(packageNamesToPackages.get(key)); } } return packageList; } public static ArrayList<Package> getAllPackages() { ArrayList<Package> packageList = new ArrayList<Package>(); for (String key : packageNamesToPackages.keySet()) { packageList.addAll(packageNamesToPackages.get(key)); } return packageList; } public static ArrayList<Package> searchPackageList(String searchStr, boolean limitResults) { ArrayList<Package> packageList = new ArrayList<Package>(); int i = PerlCompletionContributor.AUTO_POPUP_PACKAGE_ITEMS_LIMIT; for (String key : packageNamesToPackages.keySet()) { if (key.contains(searchStr)) { packageList.addAll(packageNamesToPackages.get(key)); if (limitResults) { i--; if (i <= 0) { break; } } } } return packageList; } public static ArrayList<Package> getPackageListFromFile(String filePath) { ArrayList<Package> packages = filePathsToPackages.get(filePath); if (packages == null) { packages = new ArrayList<Package>(); } return packages; } //SUBS public static void addSub(Sub sub) { if (!subNamesToSubs.containsKey(sub.getName())) { subNamesToSubs.put(sub.getName(), new HashSet<Sub>()); } HashSet<Sub> subSet = subNamesToSubs.get(sub.getName()); subSet.add(sub); } public static ArrayList<Sub> getSubList(String searchStr) { ArrayList<Sub> subList = new ArrayList<Sub>(); for (String key : subNamesToSubs.keySet()) { if (key.contains(searchStr)) { for (Sub sub : subNamesToSubs.get(key)) { subList.add(sub); } } } return subList; } //OTHER public static void clear() { packageNamesToPackages.clear(); pendingParentPackages.clear(); subNamesToSubs.clear(); filePathsToPackages.clear(); problematicFiles.clear(); parentsToChildrenPackageNames.clear(); totalDelays = 0; } public static void addPendingParentPackage(Package packageObj, String parentPackage) { if (packageObj != null && parentPackage != null) { pendingParentPackages.add(new PendingPackage(parentPackage, packageObj)); } else { Utils.alert("unexpected null!"); } } public static void addParentChild(String parentPackageName, String childPackageName) { if (!parentsToChildrenPackageNames.containsKey(parentPackageName)) { parentsToChildrenPackageNames.put(parentPackageName, new HashSet<String>()); } parentsToChildrenPackageNames.get(parentPackageName).add(childPackageName); } public static ArrayList<PendingPackage> getPendingParentPackages() { return pendingParentPackages; } public static void addProblematicFiles(String s) { problematicFiles.add(s); } public static ArrayList<String> getProblematicFiles() { return problematicFiles; } public static boolean isInitialized() { return initialized; } public static void setInitialized() { ModulesContainer.initialized = true; pendingParentPackages.clear(); problematicFiles.clear(); } public static void updateFile(String path, String fileContent) { if (Utils.debug) { Utils.print("updating file: " + path); } deleteFile(path); createFile(path, fileContent); } public static void renameFile(String oldPath, String path) { if (Utils.debug) { Utils.print("file renamed/moved:\nold: " + oldPath + "\nnew: " + path); } deleteFile(oldPath); if (Utils.isValidateExtension(path)) { createFile(path, null); } else { if (Utils.debug) { Utils.print("not a valid file extension - renamed file won't be parsed"); } } } public static void deleteFile(String path) { if (new File(path).isDirectory()) { return; } if (filePathsToPackages.containsKey(path)) { if (Utils.debug) { Utils.print("deleting file: " + path); } ArrayList<Package> packages = filePathsToPackages.remove(path); for (int i = 0; i < packages.size(); i++) { Package packageObj = packages.get(i); //remove package from all it's children HashSet<Package> children = packageObj.getChildren(); for (Package child : children) { if (Utils.verbose) { Utils.print("removing: " + packageObj.getQualifiedName() + " from child:" + child.getQualifiedName()); } child.setParentPackage(null); } Package parentPackage = packageObj.getParentPackage(); //remove package from it's parent if (parentPackage == null) { if (Utils.verbose) { Utils.print("no parent to remove for package: " + packageObj.getQualifiedName()); } } else { if (Utils.verbose) { Utils.print("removing: " + packageObj.getQualifiedName() + " from parent:" + packageObj.getParentPackage().getQualifiedName()); } packageObj.getParentPackage().removeChild(packageObj); } //remove package from remaining cache - make sure file path matches ArrayList<Package> cachedPackages = packageNamesToPackages.get(packageObj.getQualifiedName()); for (int j = 0; j < cachedPackages.size(); j++) { if (cachedPackages.get(j).getOriginFile().equals(packageObj.getOriginFile())) { cachedPackages.remove(cachedPackages.get(j)); j--; } } } } } public static void createFile(final String path, final String fileContent) { if (new File(path).isDirectory()) { return; } Thread t = new Thread(new Runnable() { @Override public void run() { if (Utils.debug) { Utils.print("creating file: " + path); } while (Utils.readFile(path).isEmpty()) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } //also happen when undoing a file deletion!!!!!!!!!!!!!!!!!!!!!!!!!!! //create package PerlInternalParser.parse(path, fileContent); //set parent package for all inheriting children ArrayList<Package> packages = ModulesContainer.getPackageListFromFile(path); for (Package packageObj : packages) { HashSet<String> children = parentsToChildrenPackageNames.get(packageObj.getQualifiedName()); if (children != null) { for (String child : children) { ArrayList<Package> childPackages = packageNamesToPackages.get(child); for (Package childPackage : childPackages) { childPackage.setParentPackage(packageObj); } } } } } }); t.start(); } public static VirtualFile getVirtualFileFromPath(Project project, String filePath) { String projectPath = project.getBaseDir().getPath(); if (filePath.startsWith(projectPath)) { filePath = filePath.substring(projectPath.length() + 1); } return project.getBaseDir().findFileByRelativePath(filePath); } }