All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gw.fs.jar.JarFileDirectoryImpl Maven / Gradle / Ivy

There is a newer version: 1.18.2
Show newest version
/*
 * Copyright 2014 Guidewire Software, Inc.
 */

package gw.fs.jar;

import gw.fs.IDirectory;
import gw.fs.IDirectoryUtil;
import gw.fs.IResource;
import gw.fs.ResourcePath;
import gw.lang.UnstableAPI;
import gw.fs.IFile;
import gw.config.CommonServices;

import java.io.IOException;
import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Enumeration;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.jar.JarFile;
import java.util.jar.JarEntry;
import java.net.URI;

@UnstableAPI
public class JarFileDirectoryImpl implements IJarFileDirectory {

  private File _file;
  private JarFile _jarFile;
  private Map _resources;
  private List _childDirs;
  private List _childFiles;

  public JarFileDirectoryImpl(File file) {
    _resources = new HashMap();
    _childFiles = new ArrayList();
    _childDirs = new ArrayList();
    _file = file;

    if (file.exists()) {
      try {
        _jarFile = new JarFile(file);
        Enumeration entries = _jarFile.entries();
        while (entries.hasMoreElements()) {
          JarEntry e = entries.nextElement();
          processJarEntry(e);
        }
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }
  }

  private void processJarEntry(JarEntry e) {
    List pathComponents = IDirectoryUtil.splitPath(e.getName());
    if (pathComponents.isEmpty()) {
      return;
    }
    if (pathComponents.size() == 1) {
      String name = pathComponents.get(0);
      if (e.isDirectory()) {
        JarEntryDirectoryImpl resource = getOrCreateDirectory(name);
        resource.setEntry(e);
      } else {
        JarEntryFileImpl resource = getOrCreateFile(name);
        resource.setEntry(e);
      }
    } else {
      JarEntryDirectoryImpl parentDirectory = getOrCreateDirectory(pathComponents.get(0));
      for (int i = 1; i < pathComponents.size() - 1; i++) {
        parentDirectory = parentDirectory.getOrCreateDirectory(pathComponents.get(i));
      }

      if (e.isDirectory()) {
        JarEntryDirectoryImpl leafDir = parentDirectory.getOrCreateDirectory(pathComponents.get(pathComponents.size() - 1));
        leafDir.setEntry(e);
      } else {
        JarEntryFileImpl leafFile = parentDirectory.getOrCreateFile(pathComponents.get(pathComponents.size() - 1));
        leafFile.setEntry(e);
      }
    }
  }

  public InputStream getInputStream(JarEntry entry) throws IOException {
    return _jarFile.getInputStream(entry);
  }

  // IJarFileDirectory methods

  @Override
  public JarEntryDirectoryImpl getOrCreateDirectory(String relativeName) {
    IResource resource = _resources.get(relativeName);
    if(resource instanceof IFile){
      throw new UnsupportedOperationException("The requested resource " + relativeName + " is now being accessed as a directory, but was previously accessed as a file.");
    }
    JarEntryDirectoryImpl result = (JarEntryDirectoryImpl) resource;
    if (result == null) {
      result = new JarEntryDirectoryImpl(relativeName, this, this);
      _resources.put(relativeName, result);
      _childDirs.add(result);
    }
    return result;
  }

  @Override
  public JarEntryFileImpl getOrCreateFile(String relativeName) {
    IResource resource = _resources.get(relativeName);
    if(resource instanceof IDirectory){
      throw new UnsupportedOperationException("The requested resource " + relativeName + " is now being accessed as a file, but was previously accessed as a directory.");
    }
    JarEntryFileImpl result = (JarEntryFileImpl) resource;
    if (result == null) {
      result = new JarEntryFileImpl(relativeName, this, this);
      _resources.put(relativeName, result);
      _childFiles.add(result);
    }
    return result;
  }

  // IDirectory methods

    @Override
  public IDirectory dir(String relativePath) {
    return IDirectoryUtil.dir(this, relativePath);
  }

  @Override
  public IFile file(String path) {
    return IDirectoryUtil.file(this, path);
  }

  @Override
  public boolean mkdir() throws IOException {
    throw new UnsupportedOperationException();
  }

  @Override
  public List listDirs() {
    List results = new ArrayList();
    for (IDirectory child : _childDirs) {
      if (child.exists()) {
        results.add(child);
      }
    }
    return results;
  }

  @Override
  public List listFiles() {
    List results = new ArrayList();
    for (IFile child : _childFiles) {
      if (child.exists()) {
        results.add(child);
      }
    }
    return results;
  }

  @Override
  public String relativePath(IResource resource) {
    return IDirectoryUtil.relativePath(this, resource);
  }

  @Override
  public IDirectory getParent() {
    File parentFile = _file.getParentFile();
    if (parentFile != null) {
      return CommonServices.getFileSystem().getIDirectory(parentFile);
    } else {
      return null;
    }
  }

  @Override
  public String getName() {
    return _file.getName();
  }

  @Override
  public boolean exists() {
    return _file.exists();
  }

  @Override
  public boolean delete() throws IOException {
    return _file.delete();
  }

  @Override
  public URI toURI() {
    return _file.toURI();
  }

  @Override
  public ResourcePath getPath() {
    return ResourcePath.parse(_file.getAbsolutePath());
  }

  @Override
  public boolean isChildOf(IDirectory dir) {
    return dir.equals(getParent());
  }

  @Override
  public boolean isDescendantOf(IDirectory dir) {
    return dir.getPath().isDescendant(getPath());
  }

  @Override
  public File toJavaFile() {
    return _file;
  }

  public JarFile getJarFile()
  {
    return _jarFile;
  }

  @Override
  public boolean isJavaFile() {
    return true;
  }

  @Override
  public boolean isInJar() {
    return true;
  }

  @Override
  public boolean create() {
    return false;
  }

  @Override
  public String toString() {
    return toJavaFile().getPath();
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }

    if (obj instanceof JarFileDirectoryImpl) {
      return getPath().equals(((JarFileDirectoryImpl) obj).getPath());
    } else {
      return false;
    }
  }

  @Override
  public void clearCaches() {
  }

  @Override
  public boolean hasChildFile(String path) {
    IFile childFile = file(path);
    return childFile != null && childFile.exists();
  }

  @Override
  public boolean isAdditional() {
    return false;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy