Package com.google.devtools.depan.java.bytecode.eclipse

Source Code of com.google.devtools.depan.java.bytecode.eclipse.NewGraphWizard

/*
* Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.devtools.depan.java.bytecode.eclipse;

import com.google.common.collect.Lists;
import com.google.devtools.depan.eclipse.editors.GraphDocument;
import com.google.devtools.depan.eclipse.utils.Resources;
import com.google.devtools.depan.eclipse.wizards.AbstractAnalysisWizard;
import com.google.devtools.depan.eclipse.wizards.ProgressListenerMonitor;
import com.google.devtools.depan.filesystem.FileSystemResources;
import com.google.devtools.depan.filesystem.eclipse.TreeLoader;
import com.google.devtools.depan.java.JavaResources;
import com.google.devtools.depan.model.GraphModel;
import com.google.devtools.depan.model.builder.DependenciesDispatcher;
import com.google.devtools.depan.model.builder.DependenciesListener;
import com.google.devtools.depan.model.builder.ElementFilter;
import com.google.devtools.depan.util.ProgressListener;
import com.google.devtools.depan.util.QuickProgressListener;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.logging.Logger;
import java.util.zip.ZipFile;

/**
* Wizard for converting a set of Java {@code .class} files into a DepAn
* analysis graph.  Based on user input, it can read for a {@code .jar} file
* or a directory tree.
*/
public class NewGraphWizard extends AbstractAnalysisWizard {

  private static final Logger logger =
      Logger.getLogger(NewGraphWizard.class.getName());

  private final ClassAnalysisStats analysisStats = new ClassAnalysisStats();

  private NewGraphPage page;

  /**
   * Constructor for NewGraphWizard.
   */
  public NewGraphWizard() {
    super();
    setNeedsProgressMonitor(true);
  }

  /**
   * Adding the page to the wizard.
   */
  @Override
  public void addPages() {
    page = new NewGraphPage(getSelection());
    addPage(page);
  }

  @Override
  protected String getOutputFileName() {
    return page.getOutputFileName();
  }

  @Override
  protected IFile getOutputFile() throws CoreException {
    return page.getOutputFile();
  }

  @Override
  protected int countAnalysisWork() {
    return 2;
  }

  /**
   * Create an analysis graph by analyzing the .class files on the classpath.
   */
  @Override
  protected GraphDocument generateAnalysisDocument(IProgressMonitor monitor)
      throws IOException {

    // Step 1) Create the GraphModel to hold the analysis results
    String classPath = page.getClassPath();
    String directoryFilter = page.getDirectoryFilter();
    String packageFilter = page.getPackageFilter();

    // TODO(leeca): Extend UI to allow lists of packages.
    Collection<String> packageWhitelist = splitFilter(packageFilter);
    ElementFilter filter = new DefaultElementFilter(packageWhitelist);

    GraphModel resultGraph = new GraphModel();
    DependenciesListener builder =
        new DependenciesDispatcher(filter, resultGraph.getBuilder());

    // TODO(leeca): Extend UI to allow lists of directories.
    Collection<String> directoryWhitelist = splitFilter(directoryFilter);

    monitor.worked(1);

    // Step 2) Read in the class files, depending on the source
    monitor.setTaskName("Load Classes...");

    ProgressListener baseProgress = new ProgressListenerMonitor(monitor);
    ProgressListener quickProgress = new QuickProgressListener(
        baseProgress, 300);

    if (classPath.endsWith(".jar") || classPath.endsWith(".zip")) {
      readZipFile(classPath, builder, quickProgress);
    } else {
      readTree(classPath, builder, quickProgress);
    }

    logger.info(
        analysisStats.getClassesLoaded() + "/" + analysisStats.getClassesTotal()
        + " classes loaded. " + analysisStats.getClassesFailed() + " failed.");

    monitor.worked(1);

    return createGraphDocument(resultGraph,
      JavaResources.PLUGIN_ID, FileSystemResources.PLUGIN_ID,
      Resources.PLUGIN_ID);
  }

  /**
   * Build Java dependencies from a Jar file.
   *
   * @param classPath path to Jar file
   * @param builder destination of discovered dependencies
   * @param progress indicator for user interface
   * @throws IOException
   */
  private void readZipFile(
      String classPath, DependenciesListener builder,
      ProgressListener progress) throws IOException {

    ClassFileReader reader = new ClassFileReader(analysisStats);
    ZipFile zipFile = new ZipFile(classPath);
    JarFileLister jarReader =
        new JarFileLister(zipFile, builder, reader, progress);
    jarReader.start();
  }

  /**
   * Build Java dependencies from a file system tree.
   *
   * @param classPath root of directory tree
   * @param builder destination of discovered dependencies
   * @param progress indicator for user interface
   * @throws IOException
   */
  private void readTree(
      String classPath, DependenciesListener builder,
      ProgressListener progress) throws IOException {

    // TODO(leeca): Instead of just assuming one level of path retention,
    // let the user decide like in NewFileSystemWizard.  But first, that needs
    // to be cleaned up and refactored.
    String treePrefix = new File(classPath).getParent();

    ClassFileReader reader = new ClassFileReader(analysisStats);

    TreeLoader loader =
        new ClassTreeLoader(treePrefix, builder, reader, progress);
    loader.analyzeTree(classPath);
  }

  /**
   * For now, split a filter input line into a filter whitelist.  In the future
   * a better UI would be appropriate.
   *
   * Split the input line on spaces, and build up the whitelist from the split()
   * results.  If the generated whitelist is empty, add on empty string to the
   * whitelist so that it matches all packages or directories.
   *
   * @param formFilter user input with possibly multiple patterns
   *     for a whitelist
   * @return Collection of Strings suitable for a whitelist.
   */
  private Collection<String> splitFilter(String formFilter) {
    Collection<String> result = Lists.newArrayList();
    for (String filter : formFilter.split("\\p{Space}+")) {
      if ((filter != null) && (!filter.isEmpty())) {
        result.add(filter);
      }
    }

    // If the constructed filter wound up empty, make it accept everything
    if (result.size() <= 0) {
      result.add("");
    }
    return result;
  }
}
TOP

Related Classes of com.google.devtools.depan.java.bytecode.eclipse.NewGraphWizard

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.