/* * 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. * *

* This is the primary object to keep track of files and directory to be * recorded in an ISO-9660 image. * *

* To create an ISO image, you have to create a IsoVolume * 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 invalidating 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 null. */ /* * 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 null 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 null 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 null. */ 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"); } }