Package org.rascalmpl.uri

Source Code of org.rascalmpl.uri.JarInputStreamURIResolver

package org.rascalmpl.uri;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
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.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

public class JarInputStreamURIResolver implements IURIInputStreamResolver {
  private URIResolverRegistry registry;
  private URI jarURI;
  private String scheme;
  private Map<String, Integer> index;

  public JarInputStreamURIResolver(URI jarURI, URIResolverRegistry registry) {
    this.jarURI = jarURI;
    this.registry = registry;
    this.scheme = "jarstream+" + UUID.randomUUID();
    buildIndex();
  }
 
  public InputStream getJarStream() throws IOException {
    return registry.getInputStream(jarURI);
  }

  private void buildIndex() {
    index = new HashMap<>();
   
    try (JarInputStream stream = new JarInputStream(getJarStream())) {
      JarEntry next = null;
      int pos = 0;
     
      while ((next = stream.getNextJarEntry()) != null) {
        index.put(next.getName(), pos++);
      }
    } catch (IOException e) {
      e.printStackTrace();
      index = null;
    }   
  }
 
  private JarEntry getEntry(JarInputStream stream, String file) throws IOException {
    if (file.startsWith("/")) {
      file = file.substring(1);
    }
    Integer pos = index == null ? null : index.get(file);
   
    if (pos != null) {
      JarEntry entry;
      do {
        entry = stream.getNextJarEntry();
      } while (pos-- > 0);
     
      return entry;
    }
   
    return null;
  }
 
  @Override
  public InputStream getInputStream(URI uri) throws IOException {
    try (JarInputStream stream = new JarInputStream(getJarStream())) {
      if (getEntry(stream, uri.getPath()) != null) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        int len;
        while ((len = stream.read(buf)) > 0) {
          out.write(buf, 0, len);
        }
       
        return new ByteArrayInputStream(out.toByteArray());
      }
    }
   
    return null;
  }

  @Override
  public Charset getCharset(URI uri) throws IOException {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public boolean exists(URI uri) {
    String file = uri.getPath();
    if (file.startsWith("/")) {
      file = file.substring(1);
    }
    return index.containsKey(file);
  }

  @Override
  public long lastModified(URI uri) throws IOException {
    try (JarInputStream stream = new JarInputStream(getJarStream())) {
      JarEntry je = getEntry(stream, uri.getPath());
      if (je != null) {
        return je.getTime();
      }
    }
   
    throw new FileNotFoundException(uri.toString());
  }

  @Override
  public boolean isDirectory(URI uri) {
    try (JarInputStream stream = new JarInputStream(getJarStream())) {
      JarEntry je = getEntry(stream, uri.getPath());
      if (je != null) {
        return je.isDirectory();
      }
    } catch (IOException e) {
      return false;
    }
   
    return false;
  }

  @Override
  public boolean isFile(URI uri) {
    return !isDirectory(uri);
  }

  @Override
  public String[] listEntries(URI uri) throws IOException {
    String path = uri.getPath();

    if (!path.endsWith("/") && !path.isEmpty()) {
      path = path + "/";
    }

    ArrayList<String> matchedEntries = new ArrayList<String>();

    try (JarInputStream stream = new JarInputStream(getJarStream())) {
      JarEntry je = null;

      while ((je = stream.getNextJarEntry()) != null) {
        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);
            }
          }
        }
      }
    }

    String[] listedEntries = new String[matchedEntries.size()];
    return matchedEntries.toArray(listedEntries);
  }

  @Override
  public String scheme() {
    return scheme;
  }

  @Override
  public boolean supportsHost() {
    return false;
  }
 
 
}
TOP

Related Classes of org.rascalmpl.uri.JarInputStreamURIResolver

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.