Пример #1
0
  public static CompareResult compare(List<String> oldIds, List<String> ids) {
    CompareResult compareResult = new CompareResult();

    int diff = oldIds.size() - ids.size();

    if (diff == 0 && isTheSame(oldIds, ids)) {
      compareResult.setResult(Result.SAME_ITEMS);
      return compareResult;
    } else if (diff == -1) {
      int position = getAddedItemPosition(oldIds, ids);
      if (position != -1) {
        compareResult.setResult(Result.ONE_ITEM_ADDED);
        compareResult.setChangedPosition(position);
        return compareResult;
      }
    } else if (diff == 1) {
      int position = getRemovedItemPosition(oldIds, ids);
      if (position != -1) {
        compareResult.setResult(Result.ONE_ITEM_REMOVED);
        compareResult.setChangedPosition(position);
        return compareResult;
      }
    }
    compareResult.setResult(Result.MANY_ITEMS_CHANGED);
    return compareResult;
  }
Пример #2
0
  public void execute() {
    if (destDir == null) throw new BuildException("The destdir attribute must be set");

    if (type == null) throw new BuildException("The type attribute must be set");

    log("Comparing files");

    final Map<String, SourceFile> vmFiles = vmDirs.scanJavaFiles(getProject());
    final Map<String, SourceFile> classpathFiles = classpathDirs.scanJavaFiles(getProject());
    final Map<String, SourceFile> vmSpecificFiles = vmSpecificDirs.scanJavaFiles(getProject());
    final TreeSet<String> allFiles = new TreeSet<String>();
    final Map<String, String> packageDiffs = new TreeMap<String, String>();
    allFiles.addAll(vmFiles.keySet());
    allFiles.addAll(classpathFiles.keySet());

    try {
      destDir.mkdirs();

      int n = Runtime.getRuntime().availableProcessors() * 2;

      ExecutorService es = Executors.newFixedThreadPool(n);

      class CompareCallable implements Callable<Collection<CompareResult>> {
        private Collection<String> files;

        CompareCallable(Collection<String> files) {
          this.files = files;
        }

        @Override
        public Collection<CompareResult> call() throws Exception {
          ArrayList<CompareResult> results = new ArrayList<CompareResult>();
          for (String name : files) {
            SourceFile cpFile = classpathFiles.get(name);
            final SourceFile vmFile = vmFiles.get(name);
            final SourceFile vmSpecificFile = vmSpecificFiles.get(name);

            if (vmSpecificFile != null) {
              // File is found as vm specific source
              results.add(new VmSpecificResult(name, vmSpecificFile.getReportName()));
            } else if (vmFile == null) {
              // file is not found as vmspecific source, nor as vm source
              if (!cpFile.isIgnoreMissing()) {
                results.add(
                    new MissingResult(name, cpFile.getReportName(), type, getFlags(cpFile)));
              }
            } else if (cpFile == null) {
              // File is not found in classpath sources
              results.add(new MissingResult(name, vmFile.getReportName(), "vm", new Flags()));
            } else {
              // We have both the classpath version and the vm version.
              cpFile = cpFile.getBestFileForTarget(vmFile.getTarget());
              // Let's compare them
              final String diffFileName = vmFile.getReportName() + ".diff";
              Flags rc = runDiff(vmFile, cpFile, diffFileName, packageDiffs);
              switch (rc.asInt() & ~FLAGS_MASK) {
                case NO_CHANGE:
                  break;
                case NEEDS_MERGE:
                  results.add(
                      new NeedsMergeResult(
                          name,
                          vmFile.getReportName(),
                          vmFile.getTarget(),
                          diffFileName,
                          rc.mask(FLAGS_MASK)));
                  break;
                default:
                  throw new RuntimeException("Invalid rc " + rc);
              }
              if (rc.isSet(FLAG_VM_SPECIFIC)) {
                results.add(new CounterResult(name, "FLAG_VM_SPECIFIC"));
              }
              if (rc.isSet(FLAG_CLASSPATH_BUGFIX)) {
                results.add(new CounterResult(name, "FLAG_CLASSPATH_BUGFIX"));
              }
              if (rc.isSet(FLAG_NATIVE)) {
                results.add(new CounterResult(name, "FLAG_NATIVE"));
              }
              if (rc.isSet(FLAG_JNODE)) {
                results.add(new CounterResult(name, "FLAG_JNODE"));
              }

              if (rc.getBugIDs().length > 0) {
                results.add(
                    new ClasspathBugsResult(name, vmFile.getReportName(), vmFile.getTarget(), rc));
              }
            }
          }
          return results;
        }
      }

      ArrayList<String> al = new ArrayList<String>();
      al.addAll(allFiles);

      CompareCallable[] tasks = new CompareCallable[n];

      for (int i = 0; i < n; i++) {
        tasks[i] = new CompareCallable(al.subList(i * al.size() / n, (i + 1) * al.size() / n));
      }

      List<Future<Collection<CompareResult>>> futures = es.invokeAll(Arrays.asList(tasks));

      es.shutdown();
      es.awaitTermination(1, TimeUnit.HOURS);

      ArrayList<CompareResult> results = new ArrayList<CompareResult>();

      for (Future<Collection<CompareResult>> future : futures) {
        if (future.isDone()) {
          try {
            results.addAll(future.get());
          } catch (ExecutionException x) {
            throw new RuntimeException(x);
          }
        } else {
          throw new RuntimeException("Future is not done: " + future);
        }
      }

      Collections.sort(results);

      log("Generating reports");

      final File outBugsFile = new File(destDir, "bugfix.html");
      final PrintWriter outBugs = new PrintWriter(new FileWriter(outBugsFile));
      reportHeader(outBugs, "Class", "Target", "Classpath bugs");

      final File outFile = new File(destDir, "index.html");
      final PrintWriter out = new PrintWriter(new FileWriter(outFile));
      reportHeader(out, "Class", "Target", "Merge status");

      int missingInCp = 0;
      int missingInVm = 0;
      int needsMerge = 0;
      int diffVmSpecific = 0;
      int diffClasspathBugfix = 0;
      int diffNative = 0;
      int diffJNode = 0;
      int vmSpecific = 0;

      for (CompareResult result : results) {
        if (result instanceof VmSpecificResult) {
          result.reportResult(out);
          vmSpecific++;
        } else if (result instanceof MissingResult) {
          result.reportResult(out);
          MissingResult missingResult = (MissingResult) result;
          if (missingResult.type.equals("vm")) {
            missingInCp++;
          } else {
            missingInVm++;
          }
        } else if (result instanceof NeedsMergeResult) {
          result.reportResult(out);
          needsMerge++;
        } else if (result instanceof CounterResult) {
          CounterResult counterResult = (CounterResult) result;
          if (counterResult.counter.equals("FLAG_VM_SPECIFIC")) {
            diffVmSpecific++;
          } else if (counterResult.counter.equals("FLAG_CLASSPATH_BUGFIX")) {
            diffClasspathBugfix++;
          } else if (counterResult.counter.equals("FLAG_NATIVE")) {
            diffNative++;
          } else if (counterResult.counter.equals("FLAG_JNODE")) {
            diffJNode++;
          }
        } else if (result instanceof ClasspathBugsResult) {
          result.reportResult(outBugs);
        } else {
          new RuntimeException("Unknown compare result: " + result);
        }
      }

      // Package diffs
      for (Map.Entry<String, String> entry : packageDiffs.entrySet()) {
        final String pkg = entry.getKey();
        final String diff = entry.getValue();
        final String diffFileName = pkg + ".pkgdiff";
        processPackageDiff(diffFileName, pkg, diff);
        reportPackageDiff(out, pkg, diffFileName, getFlags(diff));
      }

      out.println("</table><p/>");

      // Summary
      out.println("<a name='summary'/><h2>Summary</h2>");
      if (missingInCp > 0) {
        out.println("Found " + missingInCp + " files missing in " + type + "</br>");
        log("Found " + missingInCp + " files missing in " + type);
      }
      if (missingInVm > 0) {
        out.println("Found " + missingInVm + " files missing in vm<br/>");
        log("Found " + missingInVm + " files missing in vm");
      }
      if (needsMerge > 0) {
        out.println("Found " + needsMerge + " files that needs merging<br/>");
        log("Found " + needsMerge + " files that needs merging");
      }
      if (diffVmSpecific > 0) {
        out.println("Found " + diffVmSpecific + " VM specific differences<br/>");
        log("Found " + diffVmSpecific + " VM specific differences");
      }
      if (vmSpecific > 0) {
        out.println("Found " + vmSpecific + " VM specific files<br/>");
        log("Found " + vmSpecific + " VM specific files");
      }
      if (diffClasspathBugfix > 0) {
        out.println(
            "Found "
                + diffClasspathBugfix
                + " local <a href=\"bugfix.html\">classpath bugfixes</a><br/>");
        log("Found " + diffClasspathBugfix + " local classpath bugfixes");
      }
      if (diffNative > 0) {
        out.println("Found " + diffNative + " changes with native in it<br/>");
        log("Found " + diffNative + " changes with native in it");
      }
      if (diffJNode > 0) {
        out.println("Found " + diffJNode + " changes with JNode in it<br/>");
        log("Found " + diffJNode + " changes with JNode in it");
      }

      reportFooter(out);
      out.flush();
      out.close();

      reportFooter(outBugs);
      outBugs.flush();
      outBugs.close();
    } catch (IOException ex) {
      throw new BuildException(ex);
    } catch (InterruptedException ex) {
      throw new BuildException(ex);
    }
  }