Package org.rascalmpl.uri

Source Code of org.rascalmpl.uri.JarURIResolver

/*******************************************************************************
* Copyright (c) 2009-2013 CWI
* 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:

*   * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI
*   * Arnold Lankamp - Arnold.Lankamp@cwi.nl
*******************************************************************************/
package org.rascalmpl.uri;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class JarURIResolver implements IURIInputStreamResolver{
 
  public JarURIResolver() {
    super();
  }
 
  private String getJar(URI uri) throws IOException {
    String path = uri.getPath();
    if (path == null) {
      path = uri.toString();
    }
    int bang = path.indexOf('!');
    if (bang != -1) {
      return path.substring(path.indexOf("/"), bang);
    }
    else {
      throw new IOException("The jar and the internal path should be seperated with a !");
    }
  }
 
  private String getPath(URI uri) {
    String path = uri.getPath();
    if (path == null) {
      path = uri.toString();
    }
    int bang = path.indexOf('!');
   
    if (bang != -1) {
      path = path.substring(bang + 1);
      while (path.startsWith("/")) {
        path = path.substring(1);
      }
      return path;
    }
    else {
      return "";
    }
  }
 
  public InputStream getInputStream(URI uri) throws IOException {
    String jar = getJar(uri);
    String path = getPath(uri);
   
    @SuppressWarnings("resource")
    // jarFile's are closed the moment when there are no more references to it.
    JarFile jarFile = new JarFile(jar);
    JarEntry jarEntry = jarFile.getJarEntry(path);
    return jarFile.getInputStream(jarEntry);
  }
 
  public boolean exists(URI uri) {
    try {
      String jar = getJar(uri);
      String path = getPath(uri);
     
     
     
      JarFile jarFile = new JarFile(jar);
      JarEntry jarEntry = jarFile.getJarEntry(path);
      jarFile.close();
      return(jarEntry != null);
    } catch (IOException e) {
      return false;
    }
  }
 
  public boolean isDirectory(URI uri){
    try {
      if (uri.getPath() != null && uri.getPath().endsWith(".jar!")) {
        // if the uri is the root of a jar, and it ends with a !, it should be considered a directory
        return true;
      }
      String jar = getJar(uri);
      String path = getPath(uri);
     
      if (!path.endsWith("/")) {
        path = path + "/";
      }
     
      JarFile jarFile = new JarFile(jar);
      try {
        JarEntry jarEntry = jarFile.getJarEntry(path);
        if (jarEntry != null && jarEntry.isDirectory()) {
          return true;
        }
        // maybe the path is not in the jar as a seperate entry, but there are files in the path
        Enumeration<JarEntry> entries =  jarFile.entries();
        while (entries.hasMoreElements()) {
          if (entries.nextElement().getName().startsWith(path)) {
            return true;
          }
        }
        return false;
      }
      finally {
        jarFile.close();
      }
    } catch (IOException e) {
      return false;
    }
  }
 
  public boolean isFile(URI uri){
    try {
      String jar = getJar(uri);
      String path = getPath(uri);
     
      JarFile jarFile = new JarFile(jar);
      JarEntry jarEntry = jarFile.getJarEntry(path);
      jarFile.close();
      return(jarEntry != null && !jarEntry.isDirectory());
    } catch (IOException e) {
      return false;
    }
  }
 
  public long lastModified(URI uri) throws IOException{
    String jar = getJar(uri);
    String path = getPath(uri);
   
    JarFile jarFile = new JarFile(jar);
    JarEntry jarEntry = jarFile.getJarEntry(path);
    jarFile.close();
   
    if (jarEntry == null) {
      throw new FileNotFoundException(uri.toString());
    }
   
    return jarEntry.getTime();
  }
 
  public String[] listEntries(URI uri) throws IOException {
    String jar = getJar(uri);
    String path = getPath(uri);
   
    if (!path.endsWith("/") && !path.isEmpty()) {
      path = path + "/";
    }
   
    JarFile jarFile = new JarFile(jar);
   
    Enumeration<JarEntry> entries =  jarFile.entries();
    ArrayList<String> matchedEntries = new ArrayList<String>();
    while (entries.hasMoreElements()) {
      JarEntry je = entries.nextElement();
      String name = je.getName();
     
      if (name.equals(path)) {
        continue;
      }
      int index = name.indexOf(path);
     
      if (index == 0) {
        String result = name.substring(path.length());
       
        index = result.indexOf("/");
       
        if (index == -1) {
          matchedEntries.add(result);
        } else {
          result = result.substring(0, index);
          boolean entryPresent = false;
          for (Iterator<String> it = matchedEntries.iterator(); it.hasNext(); ) {
            if (result.equals(it.next())) {
              entryPresent = true;
              break;
            }
          }
          if (!entryPresent) {
            matchedEntries.add(result);
          }
        }
      }
    }
    jarFile.close();
   
    String[] listedEntries = new String[matchedEntries.size()];
    return matchedEntries.toArray(listedEntries);
  }
 
  public String scheme() {
    return "jar";
  }

  public boolean supportsHost() {
    return false;
  }

  @Override
  public Charset getCharset(URI uri) throws IOException {
    // TODO need to see if we can detect the charset inside a jar
    return null;
  }
}
TOP

Related Classes of org.rascalmpl.uri.JarURIResolver

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.