/**
   * Creates the complete package path given by the user (all filled with __init__) and returns the
   * last __init__ module created.
   */
  public static IFile createPackage(
      IProgressMonitor monitor, IContainer validatedSourceFolder, String packageName)
      throws CoreException {
    IFile lastFile = null;
    if (validatedSourceFolder == null) {
      return null;
    }
    IContainer parent = validatedSourceFolder;
    for (String packagePart : StringUtils.dotSplit(packageName)) {
      IFolder folder = parent.getFolder(new Path(packagePart));
      if (!folder.exists()) {
        folder.create(true, true, monitor);
      }
      parent = folder;
      IFile file =
          parent.getFile(
              new Path("__init__" + FileTypesPreferencesPage.getDefaultDottedPythonExtension()));
      if (!file.exists()) {
        file.create(new ByteArrayInputStream(new byte[0]), true, monitor);
      }
      lastFile = file;
    }

    return lastFile;
  }
Example #2
0
  /** @return if the paths maps to a valid python module (depending on its extension). */
  public static boolean isValidFileMod(String path) {

    boolean ret = false;
    if (isValidSourceFile(path)) {
      ret = true;

    } else if (FileTypesPreferencesPage.isValidDll(path)) {
      ret = true;
    }

    return ret;
  }
Example #3
0
 /** @return if the path passed belongs to a valid python source file (checks for the extension) */
 public static boolean isValidSourceFile(String path) {
   path = path.toLowerCase();
   for (String end : FileTypesPreferencesPage.getDottedValidSourceFiles()) {
     if (path.endsWith(end)) {
       return true;
     }
   }
   if (path.endsWith(".pypredef")) {
     return true;
   }
   return false;
 }
Example #4
0
  public static void buildKeysForRegularEntries(
      IProgressMonitor monitor,
      ModulesFoundStructure modulesFound,
      PyPublicTreeMap<ModulesKey, ModulesKey> keys,
      boolean includeOnlySourceModules) {
    String[] dottedValidSourceFiles = FileTypesPreferencesPage.getDottedValidSourceFiles();

    int j = 0;
    FastStringBuffer buffer = new FastStringBuffer();
    // now, create in memory modules for all the loaded files (empty modules).
    for (Iterator<Map.Entry<File, String>> iterator =
            modulesFound.regularModules.entrySet().iterator();
        iterator.hasNext() && monitor.isCanceled() == false;
        j++) {
      Map.Entry<File, String> entry = iterator.next();
      String m = entry.getValue();

      if (m != null) {
        if (j % 20 == 0) {
          // no need to report all the time (that's pretty fast now)
          buffer.clear();
          monitor.setTaskName(buffer.append("Module resolved: ").append(m).toString());
          monitor.worked(1);
        }

        // we don't load them at this time.
        File f = entry.getKey();

        if (includeOnlySourceModules) {
          // check if we should include only source modules
          if (!PythonPathHelper.isValidSourceFile(f.getName())) {
            continue;
          }
        }
        ModulesKey modulesKey = new ModulesKey(m, f);

        // no conflict (easy)
        if (!keys.containsKey(modulesKey)) {
          keys.put(modulesKey, modulesKey);

        } else {
          // we have a conflict, so, let's resolve which one to keep (the old one or this one)
          if (PythonPathHelper.isValidSourceFile(f.getName(), dottedValidSourceFiles)) {
            // source files have priority over other modules (dlls) -- if both are source, there is
            // no real way to resolve
            // this priority, so, let's just add it over.
            keys.put(modulesKey, modulesKey);
          }
        }
      }
    }
  }
  protected File getFileStructure(File file, String withoutLastPart) {
    File f = file;
    List<String> split = StringUtils.dotSplit(withoutLastPart);
    int size = split.size();
    for (int i = 0; i < size; i++) {
      if (i == size - 1) {
        f = new File(f, split.get(i) + FileTypesPreferencesPage.getDefaultDottedPythonExtension());

      } else {
        f = new File(f, split.get(i));
      }
    }
    return f;
  }
Example #6
0
 /** @return whether an IFile is a valid source file given its extension */
 public static boolean isValidSourceFile(IFile file) {
   String ext = file.getFileExtension();
   if (ext == null) { // no extension
     return false;
   }
   ext = ext.toLowerCase();
   for (String end : FileTypesPreferencesPage.getValidSourceFiles()) {
     if (ext.equals(end)) {
       return true;
     }
   }
   if (ext.equals(".pypredef")) {
     return true;
   }
   return false;
 }
Example #7
0
  /**
   * This method returns the module that corresponds to the path passed as a parameter.
   *
   * @param name the name of the module we're looking for (e.g.: mod1.mod2)
   * @param dontSearchInit is used in a negative form because initially it was isLookingForRelative,
   *     but it actually defines if we should look in __init__ modules too, so, the name matches the
   *     old signature.
   *     <p>NOTE: isLookingForRelative description was: when looking for relative imports, we don't
   *     check for __init__
   * @return the module represented by this name
   */
  protected IModule getModule(
      boolean acceptCompiledModule, String name, IPythonNature nature, boolean dontSearchInit) {
    synchronized (lockTemporaryModules) {
      SortedMap<Integer, IModule> map = temporaryModules.get(name);
      if (map != null && map.size() > 0) {
        if (DEBUG_TEMPORARY_MODULES) {
          System.out.println("Returning temporary module: " + name);
        }
        return map.get(map.lastKey());
      }
    }
    AbstractModule n = null;
    ModulesKey keyForCacheAccess = new ModulesKey(null, null);

    if (!dontSearchInit) {
      if (n == null) {
        keyForCacheAccess.name =
            (String) StringUtils.join(".", new String[] {name, "__init__"}, null);
        n = cache.getObj(keyForCacheAccess, this);
        if (n != null) {
          name = keyForCacheAccess.name;
        }
      }
    }
    if (n == null) {
      keyForCacheAccess.name = name;
      n = cache.getObj(keyForCacheAccess, this);
    }

    if (n instanceof SourceModule) {
      // ok, module exists, let's check if it is synched with the filesystem version...
      SourceModule s = (SourceModule) n;
      if (!s.isSynched()) {
        // change it for an empty and proceed as usual.
        n = (AbstractModule) addModule(createModulesKey(s.getName(), s.getFile()));
      }
    }

    if (n instanceof EmptyModule) {
      EmptyModule e = (EmptyModule) n;

      if (e.f != null) {

        if (!e.f.exists()) {
          // if the file does not exist anymore, just remove it.
          keyForCacheAccess.name = name;
          keyForCacheAccess.file = e.f;
          doRemoveSingleModule(keyForCacheAccess);
          n = null;

        } else {
          // file exists
          n = checkOverride(name, nature, n);

          if (n instanceof EmptyModule) {
            // ok, handle case where the file is actually from a zip file...
            if (e instanceof EmptyModuleForZip) {
              EmptyModuleForZip emptyModuleForZip = (EmptyModuleForZip) e;

              if (emptyModuleForZip.pathInZip.endsWith(".class") || !emptyModuleForZip.isFile) {
                // handle java class... (if it's a class or a folder in a jar)
                n = JythonModulesManagerUtils.createModuleFromJar(emptyModuleForZip);
                n = decorateModule(n, nature);

              } else if (FileTypesPreferencesPage.isValidDll(emptyModuleForZip.pathInZip)) {
                // .pyd
                n = new CompiledModule(name, this);
                n = decorateModule(n, nature);

              } else if (PythonPathHelper.isValidSourceFile(emptyModuleForZip.pathInZip)) {
                // handle python file from zip... we have to create it getting the contents from the
                // zip file
                try {
                  IDocument doc =
                      FileUtilsFileBuffer.getDocFromZip(
                          emptyModuleForZip.f, emptyModuleForZip.pathInZip);
                  // NOTE: The nature (and so the grammar to be used) must be defined by this
                  // modules
                  // manager (and not by the initial caller)!!
                  n =
                      AbstractModule.createModuleFromDoc(
                          name, emptyModuleForZip.f, doc, this.getNature(), false);
                  SourceModule zipModule = (SourceModule) n;
                  zipModule.zipFilePath = emptyModuleForZip.pathInZip;
                  n = decorateModule(n, nature);
                } catch (Exception exc1) {
                  Log.log(exc1);
                  n = null;
                }
              }

            } else {
              // regular case... just go on and create it.
              try {
                // NOTE: The nature (and so the grammar to be used) must be defined by this modules
                // manager (and not by the initial caller)!!
                n = AbstractModule.createModule(name, e.f, this.getNature(), true);
                n = decorateModule(n, nature);
              } catch (IOException exc) {
                keyForCacheAccess.name = name;
                keyForCacheAccess.file = e.f;
                doRemoveSingleModule(keyForCacheAccess);
                n = null;
              } catch (MisconfigurationException exc) {
                Log.log(exc);
                n = null;
              }
            }
          }
        }

      } else { // ok, it does not have a file associated, so, we treat it as a builtin (this can
               // happen in java jars)
        n = checkOverride(name, nature, n);
        if (n instanceof EmptyModule) {
          if (acceptCompiledModule) {
            n = new CompiledModule(name, this);
            n = decorateModule(n, nature);
          } else {
            return null;
          }
        }
      }

      if (n != null) {
        doAddSingleModule(createModulesKey(name, e.f), n);
      } else {
        Log.log(("The module " + name + " could not be found nor created!"));
      }
    }

    if (n instanceof EmptyModule) {
      throw new RuntimeException("Should not be an empty module anymore: " + n);
    }
    if (n instanceof SourceModule) {
      SourceModule sourceModule = (SourceModule) n;
      // now, here's a catch... it may be a bootstrap module...
      if (sourceModule.isBootstrapModule()) {
        // if it's a bootstrap module, we must replace it for the related compiled module.
        n = new CompiledModule(name, this);
        n = decorateModule(n, nature);
      }
    }

    return n;
  }
  @Override
  public void addProps(
      MarkerAnnotationAndPosition markerAnnotation,
      IAnalysisPreferences analysisPreferences,
      String line,
      PySelection ps,
      int offset,
      IPythonNature nature,
      PyEdit edit,
      List<ICompletionProposal> props)
      throws BadLocationException, CoreException {
    if (nature == null) {
      return;
    }

    ICodeCompletionASTManager astManager = nature.getAstManager();
    if (astManager == null) {
      return;
    }

    if (markerAnnotation.position == null) {
      return;
    }
    IMarker marker = markerAnnotation.markerAnnotation.getMarker();
    Integer id = (Integer) marker.getAttribute(AnalysisRunner.PYDEV_ANALYSIS_TYPE);
    int start = markerAnnotation.position.offset;
    int end = start + markerAnnotation.position.length;
    ps.setSelection(start, end);
    String markerContents;
    try {
      markerContents = ps.getSelectedText();
    } catch (Exception e1) {
      return; // Selection may be wrong.
    }

    IDocument doc = ps.getDoc();
    List<String> parametersAfterCall = ps.getParametersAfterCall(end);

    switch (id) {
      case IAnalysisPreferences.TYPE_UNDEFINED_VARIABLE:
        addCreateClassOption(ps, edit, props, markerContents, parametersAfterCall);

        addCreateMethodOption(ps, edit, props, markerContents, parametersAfterCall);
        break;

      case IAnalysisPreferences.TYPE_UNDEFINED_IMPORT_VARIABLE:
        // Say we had something as:
        // import sys
        // sys.Bar
        // in which case 'Bar' is undefined
        // in this situation, the activationTokenAndQual would be "sys." and "Bar"
        // and we want to get the definition for "sys"
        String[] activationTokenAndQual = ps.getActivationTokenAndQual(true);

        if (activationTokenAndQual[0].endsWith(".")) {
          ArrayList<IDefinition> selected = findDefinitions(nature, edit, start - 2, doc);

          for (IDefinition iDefinition : selected) {

            IModule module = iDefinition.getModule();
            if (module.getFile() != null) {
              Definition definition = (Definition) iDefinition;
              File file = module.getFile();
              if (definition.ast == null) {
                // if we have no ast in the definition, it means the module itself was found (global
                // scope)

                // Add option to create class at the given module!
                addCreateClassOption(ps, edit, props, markerContents, parametersAfterCall, file);

                addCreateMethodOption(ps, edit, props, markerContents, parametersAfterCall, file);
              } else if (definition.ast instanceof ClassDef) {
                ClassDef classDef = (ClassDef) definition.ast;
                // Ok, we should create a field or method in this case (accessing a classmethod or
                // staticmethod)
                PyCreateMethodOrField pyCreateMethod = new PyCreateMethodOrField();
                String className = NodeUtils.getNameFromNameTok(classDef.name);
                pyCreateMethod.setCreateInClass(className);
                pyCreateMethod.setCreateAs(PyCreateMethodOrField.CLASSMETHOD);
                addCreateClassmethodOption(
                    ps,
                    edit,
                    props,
                    markerContents,
                    parametersAfterCall,
                    pyCreateMethod,
                    file,
                    className);
              }
            }
          }
        }
        break;

      case IAnalysisPreferences.TYPE_UNRESOLVED_IMPORT:
        // This case is the following: from other_module4 import Foo
        // with 'Foo' being undefined.
        // So, we have to suggest creating a Foo class/method in other_module4
        PyImportsHandling importsHandling = new PyImportsHandling(ps.getDoc(), false);
        int offsetLine = ps.getLineOfOffset(start);
        String selectedText = ps.getSelectedText();

        Tuple<IModule, String> found = null;
        String foundFromImportStr = null;
        boolean isImportFrom = false;
        OUT:
        for (ImportHandle handle : importsHandling) {
          if (handle.startFoundLine == offsetLine
              || handle.endFoundLine == offsetLine
              || (handle.startFoundLine < offsetLine && handle.endFoundLine > offsetLine)) {
            List<ImportHandleInfo> importInfo = handle.getImportInfo();
            for (ImportHandleInfo importHandleInfo : importInfo) {
              String fromImportStr = importHandleInfo.getFromImportStr();
              List<String> importedStr = importHandleInfo.getImportedStr();
              for (String imported : importedStr) {
                if (selectedText.equals(imported)) {
                  if (fromImportStr != null) {
                    foundFromImportStr = fromImportStr + "." + imported;
                    isImportFrom = true;
                  } else {
                    // if fromImportStr == null, it's not a from xxx import yyy (i.e.: simple
                    // import)
                    foundFromImportStr = imported;
                  }
                  try {
                    String currentModule = nature.resolveModule(edit.getEditorFile());
                    ICompletionState state =
                        CompletionStateFactory.getEmptyCompletionState(
                            nature, new CompletionCache());

                    found =
                        nature
                            .getAstManager()
                            .findModule(
                                foundFromImportStr,
                                currentModule,
                                state,
                                new SourceModule(
                                    currentModule, edit.getEditorFile(), edit.getAST(), null));
                  } catch (Exception e) {
                    Log.log(e);
                  }
                  break OUT;
                }
              }
            }
            break OUT;
          }
        }

        boolean addOptionToCreateClassOrMethod = isImportFrom;

        if (found != null && found.o1 != null) {
          // Ok, we found a module, now, it may be that we still have to create some intermediary
          // modules
          // or just create a class or method at the end.
          if (found.o1 instanceof SourceModule) {

            // if all was found, there's nothing left to create.
            if (found.o2 != null && found.o2.length() > 0) {
              SourceModule sourceModule = (SourceModule) found.o1;
              File file = sourceModule.getFile();

              if (found.o2.indexOf('.') != -1) {
                // We have to create some intermediary structure.
                if (!addOptionToCreateClassOrMethod) {

                  // Cannot create class or method from the info (only the module structure).
                  if (sourceModule.getName().endsWith(".__init__")) {
                    File f = getFileStructure(file.getParentFile(), found.o2);
                    addCreateModuleOption(ps, edit, props, markerContents, f);
                  }

                } else {
                  // Ok, the leaf may be a class or method.
                  if (sourceModule.getName().endsWith(".__init__")) {
                    String moduleName = FullRepIterable.getWithoutLastPart(sourceModule.getName());
                    String withoutLastPart = FullRepIterable.getWithoutLastPart(found.o2);
                    moduleName += "." + withoutLastPart;

                    String classOrMethodName = FullRepIterable.getLastPart(found.o2);

                    File f = getFileStructure(file.getParentFile(), withoutLastPart);
                    addCreateClassInNewModuleOption(
                        ps, edit, props, classOrMethodName, moduleName, parametersAfterCall, f);
                    addCreateMethodInNewModuleOption(
                        ps, edit, props, classOrMethodName, moduleName, parametersAfterCall, f);
                  }
                }

              } else {
                // Ok, it's all there, we just have to create the leaf.
                if (!addOptionToCreateClassOrMethod
                    || sourceModule.getName().endsWith(".__init__")) {
                  // Cannot create class or method from the info (only the module structure).
                  if (sourceModule.getName().endsWith(".__init__")) {
                    File f =
                        new File(
                            file.getParent(),
                            found.o2 + FileTypesPreferencesPage.getDefaultDottedPythonExtension());
                    addCreateModuleOption(ps, edit, props, markerContents, f);
                  }
                } else {
                  // Ok, the leaf may be a class or method.
                  addCreateClassOption(ps, edit, props, markerContents, parametersAfterCall, file);
                  addCreateMethodOption(ps, edit, props, markerContents, parametersAfterCall, file);
                }
              }
            }
          }

        } else if (foundFromImportStr != null) {
          // We couldn't find anything there, so, we have to create the modules structure as needed
          // and
          // maybe create a class or module at the end (but only if it's an import from).
          // Ok, it's all there, we just have to create the leaf.

          // Discover the source folder where we should create the structure.

          File editorFile = edit.getEditorFile();
          String onlyProjectPythonPathStr =
              nature.getPythonPathNature().getOnlyProjectPythonPathStr(false);
          List<String> split =
              StringUtils.splitAndRemoveEmptyTrimmed(onlyProjectPythonPathStr, '|');
          for (int i = 0; i < split.size(); i++) {
            String fullPath = FileUtils.getFileAbsolutePath(split.get(i));
            fullPath = PythonPathHelper.getDefaultPathStr(fullPath);
            split.set(i, fullPath);
          }
          HashSet<String> projectSourcePath = new HashSet<String>(split);
          if (projectSourcePath.size() == 0) {
            return; // No source folder for editor... this shouldn't happen (code analysis wouldn't
            // even run on it).
          }
          String fullPath = FileUtils.getFileAbsolutePath(editorFile);
          fullPath = PythonPathHelper.getDefaultPathStr(fullPath);
          String foundSourceFolderFullPath = null;
          if (projectSourcePath.size() == 1) {
            foundSourceFolderFullPath = projectSourcePath.iterator().next();
          } else {
            for (String string : projectSourcePath) {
              if (fullPath.startsWith(string)) {
                // Use this as the source folder
                foundSourceFolderFullPath = string;
                break;
              }
            }
          }
          if (foundSourceFolderFullPath != null) {

            if (!addOptionToCreateClassOrMethod) {
              // Cannot create class or method from the info (only the module structure).

              File f = getFileStructure(new File(foundSourceFolderFullPath), foundFromImportStr);
              addCreateModuleOption(ps, edit, props, foundFromImportStr, f);

            } else {
              // Ok, the leaf may be a class or method.
              String moduleName = FullRepIterable.getWithoutLastPart(foundFromImportStr);
              File file = getFileStructure(new File(foundSourceFolderFullPath), moduleName);
              String lastPart = FullRepIterable.getLastPart(foundFromImportStr);
              addCreateClassInNewModuleOption(
                  ps, edit, props, lastPart, moduleName, parametersAfterCall, file);
              addCreateMethodInNewModuleOption(
                  ps, edit, props, lastPart, moduleName, parametersAfterCall, file);
            }
          }
        }
        break;
    }
  }
Example #9
0
  /**
   * DAMN... when I started thinking this up, it seemed much better... (and easier)
   *
   * @param module - this is the full path of the module. Only for directories or py,pyd,dll,pyo
   *     files.
   * @return a String with the module that the file or folder should represent. E.g.: compiler.ast
   */
  public String resolveModule(
      String fullPath, final boolean requireFileToExist, List<String> pythonPathCopy) {
    fullPath = REF.getFileAbsolutePath(fullPath);
    fullPath = getDefaultPathStr(fullPath);
    String fullPathWithoutExtension;

    if (isValidSourceFile(fullPath) || FileTypesPreferencesPage.isValidDll(fullPath)) {
      fullPathWithoutExtension = FullRepIterable.headAndTail(fullPath)[0];
    } else {
      fullPathWithoutExtension = fullPath;
    }

    final File moduleFile = new File(fullPath);

    if (requireFileToExist && !moduleFile.exists()) {
      return null;
    }

    boolean isFile = moduleFile.isFile();

    // go through our pythonpath and check the beginning
    for (String pathEntry : pythonPathCopy) {

      String element = getDefaultPathStr(pathEntry);
      if (fullPath.startsWith(element)) {
        int len = element.length();
        String s = fullPath.substring(len);
        String sWithoutExtension = fullPathWithoutExtension.substring(len);

        if (s.startsWith("/")) {
          s = s.substring(1);
        }
        if (sWithoutExtension.startsWith("/")) {
          sWithoutExtension = sWithoutExtension.substring(1);
        }

        if (!isValidModuleLastPart(sWithoutExtension)) {
          continue;
        }

        s = s.replaceAll("/", ".");
        if (s.indexOf(".") != -1) {
          File root = new File(element);
          if (root.exists() == false) {
            continue;
          }

          final List<String> temp = StringUtils.dotSplit(s);
          String[] modulesParts = temp.toArray(new String[temp.size()]);

          // this means that more than 1 module is specified, so, in order to get it,
          // we have to go and see if all the folders to that module have __init__.py in it...
          if (modulesParts.length > 1 && isFile) {
            String[] t = new String[modulesParts.length - 1];

            for (int i = 0; i < modulesParts.length - 1; i++) {
              t[i] = modulesParts[i];
            }
            t[t.length - 1] = t[t.length - 1] + "." + modulesParts[modulesParts.length - 1];
            modulesParts = t;
          }

          // here, in modulesParts, we have something like
          // ["compiler", "ast.py"] - if file
          // ["pywin","debugger"] - if folder
          //
          // root starts with the pythonpath folder that starts with the same
          // chars as the full path passed in.
          boolean isValid = true;
          for (int i = 0; i < modulesParts.length && root != null; i++) {
            root = new File(REF.getFileAbsolutePath(root) + "/" + modulesParts[i]);

            // check if file is in root...
            if (isValidFileMod(modulesParts[i])) {
              if (root.exists() && root.isFile()) {
                break;
              }

            } else {
              // this part is a folder part... check if it is a valid module (has init).
              if (isFileOrFolderWithInit(root) == false) {
                isValid = false;
                break;
              }
              // go on and check the next part.
            }
          }
          if (isValid) {
            if (isFile) {
              s = stripExtension(s);
            } else if (moduleFile.exists() == false) {
              // ok, it does not exist, so isFile will not work, let's just check if it is
              // a valid module (ends with .py or .pyw) and if it is, strip the extension
              if (isValidFileMod(s)) {
                s = stripExtension(s);
              }
            }
            return s;
          }
        } else {
          // simple part, we don't have to go into subfolders to check validity...
          if (!isFile && moduleFile.isDirectory() && isFileOrFolderWithInit(moduleFile) == false) {
            return null;
          }
          return s;
        }
      }
    }
    // ok, it was not found in any existing way, so, if we don't require the file to exist, let's
    // just do some simpler search and get the
    // first match (if any)... this is useful if the file we are looking for has just been deleted
    if (!requireFileToExist) {
      // we have to remove the last part (.py, .pyc, .pyw)
      for (String element : pythonPathCopy) {
        element = getDefaultPathStr(element);
        if (fullPathWithoutExtension.startsWith(element)) {
          String s = fullPathWithoutExtension.substring(element.length());
          if (s.startsWith("/")) {
            s = s.substring(1);
          }
          if (!isValidModuleLastPart(s)) {
            continue;
          }
          s = s.replaceAll("/", ".");
          return s;
        }
      }
    }
    return null;
  }
Example #10
0
  /**
   * @param root the zip file to analyze
   * @param monitor the monitor, to keep track of what is happening
   * @return a list with the name of the found modules in the jar
   */
  protected static ModulesFoundStructure.ZipContents getFromZip(
      File root, IProgressMonitor monitor) {

    String fileName = root.getName();
    if (root.isFile()
        && FileTypesPreferencesPage.isValidZipFile(
            fileName)) { // ok, it may be a jar file, so let's get its contents and get the
      // available modules

      // the major difference from handling jars from regular python files is that we don't have to
      // check for __init__.py files
      ModulesFoundStructure.ZipContents zipContents = new ModulesFoundStructure.ZipContents(root);

      // by default it's a zip (for python) -- may change if a .class is found.
      zipContents.zipContentsType = ZipContents.ZIP_CONTENTS_TYPE_PY_ZIP;

      try {
        String zipFileName = root.getName();

        ZipFile zipFile = new ZipFile(root);
        try {
          Enumeration<? extends ZipEntry> entries = zipFile.entries();

          int i = 0;
          FastStringBuffer buffer = new FastStringBuffer();
          // ok, now that we have the zip entries, let's map them to modules
          while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
            String name = entry.getName();
            if (!entry.isDirectory()) {
              if (isValidFileMod(name) || name.endsWith(".class")) {

                if (name.endsWith(".class")) {
                  zipContents.zipContentsType = ZipContents.ZIP_CONTENTS_TYPE_JAR;
                }

                // it is a valid python file
                if (i % 15 == 0) {
                  if (monitor.isCanceled()) {
                    return null;
                  }
                  buffer.clear();
                  monitor.setTaskName(
                      buffer
                          .append("Found in ")
                          .append(zipFileName)
                          .append(" module ")
                          .append(name)
                          .toString());
                  monitor.worked(1);
                }

                if (isValidInitFile(name)) {
                  zipContents.pyInitFilesLowerWithoutExtension.add(
                      StringUtils.stripExtension(name).toLowerCase());
                }
                zipContents.pyFilesLowerToRegular.put(name.toLowerCase(), name);
              }

            } else { // !isDirectory
              zipContents.pyfoldersLower.add(name.toLowerCase());
            }
            i++;
          }
        } finally {
          zipFile.close();
        }

        // now, on to actually filling the structure if we have a zip file (just add the ones that
        // are actually under
        // the pythonpath)
        zipContents.consolidatePythonpathInfo(monitor);

        return zipContents;

      } catch (Exception e) {
        // that's ok, it is probably not a zip file after all...
        PydevPlugin.log(e);
      }
    }
    return null;
  }