Package com.github.junrar.vfs2.provider.rar

Source Code of com.github.junrar.vfs2.provider.rar.RARFileSystem

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.github.junrar.vfs2.provider.rar;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.vfs2.Capability;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystem;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.provider.AbstractFileName;
import org.apache.commons.vfs2.provider.AbstractFileSystem;
import org.apache.commons.vfs2.provider.UriParser;

import com.github.junrar.Archive;
import com.github.junrar.exception.RarException;
import com.github.junrar.rarfile.FileHeader;


/**
* A read-only file system for RAR files.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class RARFileSystem extends AbstractFileSystem implements FileSystem {
  private final FileObject parentLayer;

  private Archive archive;
  private Map<String, FileHeader> files = new HashMap<String, FileHeader>();

  public RARFileSystem(final AbstractFileName rootName,
      final FileObject parentLayer,
      final FileSystemOptions fileSystemOptions)
      throws FileSystemException {
    super(rootName, parentLayer, fileSystemOptions);
    this.parentLayer = parentLayer;
  }

  @Override
  public void init() throws FileSystemException {
    super.init();

    try {
      try {
        archive = new Archive(new VFSVolumeManager(parentLayer));
        // Build the index
        List<RARFileObject> strongRef = new ArrayList<RARFileObject>(
            100);
        for (final FileHeader header : archive.getFileHeaders()) {
          AbstractFileName name = (AbstractFileName) getFileSystemManager()
              .resolveName(
                  getRootName(),
                  UriParser.encode(header.getFileNameString()));

          // Create the file
          RARFileObject fileObj;
          if (header.isDirectory() && getFileFromCache(name) != null) {
            fileObj = (RARFileObject) getFileFromCache(name);
            fileObj.setHeader(header);
            continue;
          }

          fileObj = createRARFileObject(name, header);
          putFileToCache(fileObj);
          strongRef.add(fileObj);
          fileObj.holdObject(strongRef);

          // Make sure all ancestors exist
          RARFileObject parent;
          for (AbstractFileName parentName = (AbstractFileName) name
              .getParent(); parentName != null; fileObj = parent, parentName = (AbstractFileName) parentName
              .getParent()) {
            // Locate the parent
            parent = (RARFileObject) getFileFromCache(parentName);
            if (parent == null) {
              parent = createRARFileObject(parentName, null);
              putFileToCache(parent);
              strongRef.add(parent);
              parent.holdObject(strongRef);
            }

            // Attach child to parent
            parent.attachChild(fileObj.getName());
          }
        }

      } catch (RarException e) {
        throw new FileSystemException(e);
      } catch (IOException e) {
        throw new FileSystemException(e);
      }
    } finally {
      // closeCommunicationLink();
    }
  }

  protected RARFileObject createRARFileObject(final AbstractFileName name,
      final FileHeader header) throws FileSystemException {
    return new RARFileObject(name, archive, header, this);
  }

  @Override
  protected void doCloseCommunicationLink() {
    try {
      archive.close();
    } catch (FileSystemException e) {
      throw new RuntimeException(e);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Returns the capabilities of this file system.
   */
  @Override
  protected void addCapabilities(final Collection<Capability> caps) {
    caps.addAll(RARFileProvider.capabilities);
  }

  /**
   * Creates a file object.
   */
  @Override
  protected FileObject createFile(final AbstractFileName name)
      throws FileSystemException {
    String path = name.getPath().substring(1);
    if (path.length() == 0) {
      return new RARFileObject(name, archive, null, this);
    } else if (files.containsKey(name.getPath())) {
      return new RARFileObject(name, archive, files.get(name.getPath()),
          this);
    }
    return null;
  }

  /**
   * will be called after all file-objects closed their streams.
   */
  protected void notifyAllStreamsClosed() {
    closeCommunicationLink();
  }
}
TOP

Related Classes of com.github.junrar.vfs2.provider.rar.RARFileSystem

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.