com.github.junrar.vfs2.provider.rar.RARFileSystem Maven / Gradle / Ivy
/*
* 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 Rogiel
*/
public class RARFileSystem extends AbstractFileSystem implements FileSystem {
private final FileObject parentLayer;
private Archive archive;
private Map files = new HashMap();
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 strongRef = new ArrayList(
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 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();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy