291 lines
7.6 KiB
Java
291 lines
7.6 KiB
Java
|
/*
|
||
|
* IsoVolume.java
|
||
|
*
|
||
|
* Copyright (c) 2007 Vreixo Formoso
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation; either version 2 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
* See COPYING file for details.
|
||
|
*/
|
||
|
|
||
|
package org.pykix.libburnia.libisofs;
|
||
|
|
||
|
import java.io.File;
|
||
|
import java.io.FileNotFoundException;
|
||
|
|
||
|
import org.pykix.libburnia.bindings.Proxy;
|
||
|
import org.pykix.libburnia.libburn.BurnSource;
|
||
|
|
||
|
/**
|
||
|
* ISO-9660 Data volume.
|
||
|
*
|
||
|
* <p>
|
||
|
* This is the primary object to keep track of files and directory to be
|
||
|
* recorded in an ISO-9660 image.
|
||
|
*
|
||
|
* <p>
|
||
|
* To create an ISO image, you have to create a <code>IsoVolume</code>
|
||
|
* object and add files and/or directories to it. After doing so, you will
|
||
|
* want to get a {@link BurnSource} to actually write the image to a file or
|
||
|
* disc. To do this, you have to create an {@link IsoVolSet} with this object.
|
||
|
*
|
||
|
* @see IsoVolSet
|
||
|
*
|
||
|
* TODO current implementation forces user to keep a reference to this
|
||
|
* object while still having a reference to an IsoTreeNode from this. This
|
||
|
* is because of automatic memory management. Underlying iso_volume is
|
||
|
* deleted when Java object gets out of scope, and this causes all iso_tree_node
|
||
|
* to be also deleted, thus <i>invalidating</i> java objects. Without
|
||
|
* modifying libburnia code, the only way to solve this (I think) is add a ref
|
||
|
* from each IsoTreeNode. Because of space efficience and normal library usage
|
||
|
* I think current solution is better.
|
||
|
* When added to IsoVolSet there is no problem if this
|
||
|
* goes out of scope (while keeping ref. to IsoVolSet), because ref count
|
||
|
* is incremented and underlying object is not deleted.
|
||
|
*
|
||
|
* @author Vreixo Formoso
|
||
|
* @since 0.1
|
||
|
*/
|
||
|
public class IsoVolume extends Proxy {
|
||
|
|
||
|
/**
|
||
|
* Create a new volume.
|
||
|
*
|
||
|
* @param volumeId
|
||
|
* Id for the volume, can be null if you wish to set it later.
|
||
|
* @param publisherId
|
||
|
* Id for the publish, can be null if you wish to set it later.
|
||
|
* @param dataPreparerId
|
||
|
* Id for the data prepared, can be null if you wish to set it later.
|
||
|
*/
|
||
|
public IsoVolume(String volumeId, String publisherId,
|
||
|
String dataPreparerId) {
|
||
|
|
||
|
super( iso_volume_new(volumeId, publisherId, dataPreparerId) );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create a new volume.
|
||
|
*
|
||
|
* @param volumeId
|
||
|
* @param publisherId
|
||
|
* @param dataPreparerId
|
||
|
* @param root
|
||
|
*/
|
||
|
public IsoVolume(String volumeId, String publisherId,
|
||
|
String dataPreparerId, IsoTreeNode root) {
|
||
|
|
||
|
super( iso_volume_new_with_root(volumeId, publisherId, dataPreparerId,
|
||
|
pointerOf(root)) );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the root directory.
|
||
|
* @return
|
||
|
*/
|
||
|
public IsoTreeNode getRoot() {
|
||
|
|
||
|
long ptr = iso_volume_get_root( pointerOf(this) );
|
||
|
|
||
|
if (ptr == 0) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
IsoTreeNode node = (IsoTreeNode) proxyFor(ptr);
|
||
|
|
||
|
if (node == null) {
|
||
|
node = new IsoTreeNode(ptr);
|
||
|
}
|
||
|
/*
|
||
|
* FIXME a problem here is that if this IsoVolume gets out of
|
||
|
* scope, C iso_volume will be freed, thus deleting the
|
||
|
* iso_tree_node, and ptr is pointing to an invalid C object, which
|
||
|
* can lead to problems. This can also happen in C code if an user
|
||
|
* explicity free the iso_volume, but in Java is really a problem
|
||
|
* because the automatic memory management
|
||
|
*/
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Fill in the volume identifier.
|
||
|
* @param volumeId
|
||
|
*/
|
||
|
public void setVolumeId(String volumeId) {
|
||
|
iso_volume_set_volume_id(pointerOf(this), volumeId);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Fill in the publisher.
|
||
|
* @param publisherId
|
||
|
*/
|
||
|
public void setPublisherId(String publisherId) {
|
||
|
iso_volume_set_publisher_id(pointerOf(this), publisherId);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Fill in the data preparer.
|
||
|
* @param dataPreparerId
|
||
|
*/
|
||
|
public void setDataPreparerId(String dataPreparerId) {
|
||
|
iso_volume_set_data_preparer_id(pointerOf(this), dataPreparerId);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Locate a node by its path on disc.
|
||
|
*
|
||
|
* @param path
|
||
|
* The path, in the image, of the file.
|
||
|
* @return
|
||
|
* The node found or <code>null</code>.
|
||
|
*/
|
||
|
/*
|
||
|
* Take care that this is really a wrapp for iso_tree_volume_path_to_node
|
||
|
*/
|
||
|
public IsoTreeNode getNode(String path) {
|
||
|
|
||
|
long ptr = iso_tree_volume_path_to_node(pointerOf(this), path);
|
||
|
|
||
|
if (ptr == 0) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
//FIXME same problems as in getRoot
|
||
|
return (ptr == 0) ? null : new IsoTreeNode(ptr);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a file or a directory (recursively) to the volume by specifying
|
||
|
* its path on the volume.
|
||
|
*
|
||
|
* @param discPath
|
||
|
* The path on the disc at which to add the file/directory.
|
||
|
* @param path
|
||
|
* The path, on the local filesystem, of the file.
|
||
|
* @return
|
||
|
* The node for the file or <code>null</code> if the parent doesn't
|
||
|
* exists on the disc.
|
||
|
*/
|
||
|
public IsoTreeNode addPath(String discPath, String path) {
|
||
|
|
||
|
long ptr = iso_tree_volume_add_path(pointerOf(this), discPath, path);
|
||
|
|
||
|
if (ptr == 0) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
IsoTreeNode node = (IsoTreeNode) proxyFor(ptr);
|
||
|
|
||
|
if (node == null) {
|
||
|
node = new IsoTreeNode(ptr);
|
||
|
}
|
||
|
//FIXME same problems as in getRoot
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Like {@link #addPath(String, String) addPath}, but local path is
|
||
|
* passed as a {@link File}
|
||
|
*
|
||
|
* @param discPath
|
||
|
* The path on the disc at which to add the file/directory.
|
||
|
* @param path
|
||
|
* The path, on the local filesystem, of the file.
|
||
|
* @return
|
||
|
* The node for the file or <code>null</code> if the parent doesn't
|
||
|
* exists on the disc.
|
||
|
* @throws FileNotFoundException
|
||
|
* If passed local path does not exist
|
||
|
*/
|
||
|
public IsoTreeNode addPath(String discPath, File path)
|
||
|
throws FileNotFoundException {
|
||
|
|
||
|
if ( !path.exists() ) {
|
||
|
throw new FileNotFoundException(path.getPath());
|
||
|
}
|
||
|
|
||
|
long ptr = iso_tree_volume_add_path(pointerOf(this), discPath,
|
||
|
path.getPath());
|
||
|
|
||
|
if (ptr == 0) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
IsoTreeNode node = (IsoTreeNode) proxyFor(ptr);
|
||
|
|
||
|
if (node == null) {
|
||
|
node = new IsoTreeNode(ptr);
|
||
|
}
|
||
|
//FIXME same problems as in getRoot
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Creates a new, empty directory on the volume.
|
||
|
*
|
||
|
* @param discPath
|
||
|
* The path on the volume at which to add the directory.
|
||
|
* @return
|
||
|
* The newly created directory or <code>null</code>.
|
||
|
*/
|
||
|
public IsoTreeNode addNewDir(String discPath) {
|
||
|
|
||
|
long ptr = iso_tree_volume_add_new_dir(pointerOf(this), discPath);
|
||
|
|
||
|
if (ptr == 0) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
IsoTreeNode node = (IsoTreeNode) proxyFor(ptr);
|
||
|
|
||
|
if (node == null) {
|
||
|
node = new IsoTreeNode(ptr);
|
||
|
}
|
||
|
//FIXME same problems as in getRoot
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected void finalize() throws Throwable {
|
||
|
super.finalize();
|
||
|
|
||
|
/* free underlying C object */
|
||
|
iso_volume_free( pointerOf(this) );
|
||
|
}
|
||
|
|
||
|
private static native long iso_volume_new(String volumeId,
|
||
|
String publisherId, String dataPreparerId);
|
||
|
|
||
|
private static native long iso_volume_new_with_root(String volumeId,
|
||
|
String publisherId, String dataPreparerId, long root);
|
||
|
|
||
|
private static native void iso_volume_free(long volume);
|
||
|
|
||
|
private static native long iso_volume_get_root(long volume);
|
||
|
|
||
|
private static native void iso_volume_set_volume_id(long volume,
|
||
|
String volumeId);
|
||
|
|
||
|
private static native void iso_volume_set_publisher_id(long volume,
|
||
|
String publisherId);
|
||
|
|
||
|
private static native void iso_volume_set_data_preparer_id(long volume,
|
||
|
String data_preparer_id);
|
||
|
|
||
|
private static native long iso_tree_volume_path_to_node(long volume,
|
||
|
String path);
|
||
|
|
||
|
private static native long iso_tree_volume_add_path(long volume,
|
||
|
String discPath, String path);
|
||
|
|
||
|
private static native long iso_tree_volume_add_new_dir(long volume,
|
||
|
String discPath);
|
||
|
|
||
|
static {
|
||
|
System.loadLibrary("java-libburn-0.1");
|
||
|
}
|
||
|
|
||
|
}
|