Package org.eclipse.jdt.internal.compiler.batch

Source Code of org.eclipse.jdt.internal.compiler.batch.ClasspathJar

/*******************************************************************************
* Copyright (c) 2000, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.batch;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.util.ManifestAnalyzer;
import org.eclipse.jdt.internal.compiler.util.Util;

@SuppressWarnings({"rawtypes", "unchecked"})
public class ClasspathJar extends ClasspathLocation {

protected File file;
protected ZipFile zipFile;
protected boolean closeZipFileAtEnd;
protected Hashtable packageCache;

public ClasspathJar(File file, boolean closeZipFileAtEnd,
    AccessRuleSet accessRuleSet, String destinationPath) {
  super(accessRuleSet, destinationPath);
  this.file = file;
  this.closeZipFileAtEnd = closeZipFileAtEnd;
}

public List fetchLinkedJars(FileSystem.ClasspathSectionProblemReporter problemReporter) {
  // expected to be called once only - if multiple calls desired, consider
  // using a cache
  InputStream inputStream = null;
  try {
    initialize();
    ArrayList result = new ArrayList();
    ZipEntry manifest = this.zipFile.getEntry("META-INF/MANIFEST.MF"); //$NON-NLS-1$
    if (manifest != null) { // non-null implies regular file
      inputStream = this.zipFile.getInputStream(manifest);
      ManifestAnalyzer analyzer = new ManifestAnalyzer();
      boolean success = analyzer.analyzeManifestContents(inputStream);
      List calledFileNames = analyzer.getCalledFileNames();
      if (problemReporter != null) {
        if (!success || analyzer.getClasspathSectionsCount() == 1 &&  calledFileNames == null) {
          problemReporter.invalidClasspathSection(getPath());
        } else if (analyzer.getClasspathSectionsCount() > 1) {
          problemReporter.multipleClasspathSections(getPath());
        }
      }
      if (calledFileNames != null) {
        Iterator calledFilesIterator = calledFileNames.iterator();
        String directoryPath = getPath();
        int lastSeparator = directoryPath.lastIndexOf(File.separatorChar);
        directoryPath = directoryPath.substring(0, lastSeparator + 1); // potentially empty (see bug 214731)
        while (calledFilesIterator.hasNext()) {
          result.add(new ClasspathJar(new File(directoryPath + (String) calledFilesIterator.next()), this.closeZipFileAtEnd, this.accessRuleSet, this.destinationPath));
        }
      }
    }
    return result;
  } catch (IOException e) {
    return null;
  } finally {
    if (inputStream != null) {
      try {
        inputStream.close();
      } catch (IOException e) {
        // best effort
      }
    }
  }
}
public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
  return findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, false);
}
public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName, boolean asBinaryOnly) {
  if (!isPackage(qualifiedPackageName))
    return null; // most common case

  try {
    ClassFileReader reader = ClassFileReader.read(this.zipFile, qualifiedBinaryFileName);
    if (reader != null)
      return new NameEnvironmentAnswer(reader, fetchAccessRestriction(qualifiedBinaryFileName));
  } catch(ClassFormatException e) {
    // treat as if class file is missing
  } catch (IOException e) {
    // treat as if class file is missing
  }
  return null;
}
public char[][][] findTypeNames(String qualifiedPackageName) {
  if (!isPackage(qualifiedPackageName))
    return null; // most common case

  ArrayList answers = new ArrayList();
  nextEntry : for (Enumeration e = this.zipFile.entries(); e.hasMoreElements(); ) {
    String fileName = ((ZipEntry) e.nextElement()).getName();

    // add the package name & all of its parent packages
    int last = fileName.lastIndexOf('/');
    while (last > 0) {
      // extract the package name
      String packageName = fileName.substring(0, last);
      if (!qualifiedPackageName.equals(packageName))
        continue nextEntry;
      int indexOfDot = fileName.lastIndexOf('.');
      if (indexOfDot != -1) {
        String typeName = fileName.substring(last + 1, indexOfDot);
        char[] packageArray = packageName.toCharArray();
        answers.add(
          CharOperation.arrayConcat(
            CharOperation.splitOn('/', packageArray),
            typeName.toCharArray()));
      }
    }
  }
  int size = answers.size();
  if (size != 0) {
    char[][][] result = new char[size][][];
    answers.toArray(result);
    return null;
  }
  return null;
}
public void initialize() throws IOException {
  if (this.zipFile == null) {
    this.zipFile = new ZipFile(this.file);
  }
}
public boolean isPackage(String qualifiedPackageName) {
  if (this.packageCache != null)
    return this.packageCache.containsKey(qualifiedPackageName);

  this.packageCache = new Hashtable(41);
  this.packageCache.put(Util.EMPTY_STRING, Util.EMPTY_STRING);

  nextEntry : for (Enumeration e = this.zipFile.entries(); e.hasMoreElements(); ) {
    String fileName = ((ZipEntry) e.nextElement()).getName();

    // add the package name & all of its parent packages
    int last = fileName.lastIndexOf('/');
    while (last > 0) {
      // extract the package name
      String packageName = fileName.substring(0, last);
      if (this.packageCache.containsKey(packageName))
        continue nextEntry;
      this.packageCache.put(packageName, packageName);
      last = packageName.lastIndexOf('/');
    }
  }
  return this.packageCache.containsKey(qualifiedPackageName);
}
public void reset() {
  if (this.zipFile != null && this.closeZipFileAtEnd) {
    try {
      this.zipFile.close();
    } catch(IOException e) {
      // ignore
    }
    this.zipFile = null;
  }
  this.packageCache = null;
}
public String toString() {
  return "Classpath for jar file " + this.file.getPath(); //$NON-NLS-1$
}
public char[] normalizedPath() {
  if (this.normalizedPath == null) {
    String path2 = this.getPath();
    char[] rawName = path2.toCharArray();
    if (File.separatorChar == '\\') {
      CharOperation.replace(rawName, '\\', '/');
    }
    this.normalizedPath = CharOperation.subarray(rawName, 0, CharOperation.lastIndexOf('.', rawName));
  }
  return this.normalizedPath;
}
public String getPath() {
  if (this.path == null) {
    try {
      this.path = this.file.getCanonicalPath();
    } catch (IOException e) {
      // in case of error, simply return the absolute path
      this.path = this.file.getAbsolutePath();
    }
  }
  return this.path;
}
public int getMode() {
  return BINARY;
}
}
TOP

Related Classes of org.eclipse.jdt.internal.compiler.batch.ClasspathJar

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.