package org.springframework.roo.process.manager;
import java.io.InputStream;
import java.util.SortedSet;
import org.springframework.roo.file.monitor.FileMonitorService;
import org.springframework.roo.file.monitor.NotifiableFileMonitorService;
import org.springframework.roo.file.monitor.event.FileDetails;
import org.springframework.roo.file.undo.UndoManager;
/**
* Represents the primary means for add-ons to modify the underlying disk
* storage.
* <p>
* A {@link FileManager} instance is acquired from the {@link ProcessManager}. A
* {@link FileManager} implementation must guarantee to use an
* {@link UndoManager} that is available to the {@link ProcessManager}, such
* that {@link ProcessManager} can undo or reset as required.
* <p>
* An implementation may elect to defer writes to disk or discard them until
* {@link #commit()} or {@link #clear()} respectively is invoked.
*
* @author Ben Alex
* @since 1.0
*/
public interface FileManager {
/**
* Discards proposed changes to the disk that an implementation may have
* elected to defer.
*/
void clear();
/**
* Commits actual changes to the disk that an implementation may have
* elected to defer.
*/
void commit();
/**
* Attempts to create a new directory on the disk.
* <p>
* The requested file identifier path must not already exist. It should be
* in canonical file name format.
* <p>
* Parent directories must also be created automatically by this method. Any
* created parent directories should be removed as part of the undo
* behaviour.
* <p>
* An exception will be thrown if the path already exists.
*
* @param fileIdentifier a path to be created that does not already exist
* (required)
* @return a representation of the directory (or null if the creation
* failed)
*/
FileDetails createDirectory(String fileIdentifier);
/**
* Attempts to create a zero-byte file on the disk.
* <p>
* The requested fileIdentifier path must not already exist. It should be in
* canonical file name format.
* <p>
* Implementations guarantee to {@link #createDirectory(String)} as required
* to create any required parent directories.
* <p>
* An exception will be thrown if the path already exists.
*
* @param fileIdentifier a path to be created that does not already exist
* (required)
* @return a representation of the file (or null if the creation failed)
*/
MutableFile createFile(String fileIdentifier);
/**
* Provides a simple way to create or update a file, skipping any
* modification if the file's contents match the proposed contents. This
* should only be called for text files.
* <p>
* This mechanism also automatically deletes an unwanted file if the new
* contents are zero bytes. If deleting, the existence of the file need not
* be considered in advance (it will only delete if the file is present, but
* it will not fail if the file does not exist or has been separately
* deleted).
* <p>
* Implementations guarantee to {@link #createDirectory(String)} as required
* to create any required parent directories.
* <p>
* Implementations are required to observe the {@link #commit()} and
* {@link #clear()} semantics defined in the type-level JavaDocs.
*
* @param fileIdentifier the file to create or update as appropriate
* (required)
* @param newContents the replacement contents (required, but can be zero
* bytes if the file should be deleted)
* @param writeImmediately forces immediate write of the file to disk (false
* means it can be deferred, as recommended)
*/
void createOrUpdateTextFileIfRequired(String fileIdentifier, String newContents,
boolean writeImmediately);
/**
* Provides a simple way to create or update a file, skipping any
* modification if the file's contents match the proposed contents. This
* should only be called for text files.
* <p>
* This mechanism also automatically deletes an unwanted file if the new
* contents are zero bytes. If deleting, the existence of the file need not
* be considered in advance (it will only delete if the file is present, but
* it will not fail if the file does not exist or has been separately
* deleted).
* <p>
* Implementations guarantee to {@link #createDirectory(String)} as required
* to create any required parent directories.
* <p>
* Implementations are required to observe the {@link #commit()} and
* {@link #clear()} semantics defined in the type-level JavaDocs.
*
* @param fileIdentifier the file to create or update as appropriate
* (required)
* @param newContents the replacement contents (required, but can be zero
* bytes if the file should be deleted)
* @param descriptionOfChange the additional information about a change (can
* be null)
* @param writeImmediately forces immediate write of the file to disk (false
* means it can be deferred, as recommended)
*/
void createOrUpdateTextFileIfRequired(String fileIdentifier, String newContents,
String descriptionOfChange, boolean writeImmediately);
/**
* Attempts to delete a file or directory on the disk. The path should be in
* canonical file name format.
* <p>
* If the path refers to a directory, contents of the directory will be
* recursively deleted.
* <p>
* If a delete fails, an exception will be thrown.
*
* @param pathname the file to delete; can be blank to do nothing, otherwise
* should be a valid pathname as per
* {@link java.io.File#File(String)}
* @throws IllegalArgumentException if a file is specified but does not
* exist
*/
void delete(String pathname);
/**
* Attempts to delete a file or directory on the disk. The path should be in
* canonical file name format.
* <p>
* If the path refers to a directory, contents of the directory will be
* recursively deleted.
* <p>
* If a delete fails, an exception will be thrown.
*
* @param pathname the file to delete; can be blank to do nothing, otherwise
* should be a valid pathname as per
* {@link java.io.File#File(String)}
* @param reasonForDeletion the reason why the file is being deleted (can be
* blank)
* @since 1.2.0
* @throws IllegalArgumentException if a file is specified but does not
* exist
*/
void delete(String pathname, String reasonForDeletion);
/**
* Indicates whether the file identified by the passed canonical path
* exists.
*
* @param fileIdentifier the file or directory to locate (required, in
* canonical path format)
* @return true if the file or directory exists
*/
boolean exists(String fileIdentifier);
/**
* Delegates to {@link FileMonitorService#findMatchingAntPath(String)}.
*
* @param antPath the Ant path to evaluate, as per the canonical file path
* format (required)
* @return all matching identifiers (may be empty, but never null)
*/
SortedSet<FileDetails> findMatchingAntPath(String antPath);
/**
* Obtains an input stream for the indicated file identifier, which must be
* a file (not a directory) and must exist at the time the method is called.
* This method is useful if read-only access to a file is required. For
* read-write access, use one of the other methods on {@link FileManager}.
*
* @param fileIdentifier the file to read (required, in canonical path
* format)
* @return the input stream (never null)
*/
InputStream getInputStream(String fileIdentifier);
/**
* Obtains an already-existing file for reading. The path should be in
* canonical file name format.
*
* @param fileIdentifier the file to read that already exists (required)
* @return a representation of the file (or null if the file does not exist)
*/
FileDetails readFile(String fileIdentifier);
/**
* Delegates to {@link FileMonitorService#scanAll()} or
* {@link NotifiableFileMonitorService#scanNotified()} if available.
*
* @return the number of changes detected (can be 0 or above)
*/
int scan();
/**
* Provides an updatable representation of a file on the disk.
* <p>
* The file identifier must refer to a file (not directory) that already
* exists. A violation of this requirement will result in an exception. The
* identifier should be in canonical file name format.
* <p>
* Refer to the documentation for {@link MutableFile} for important
* restrictions on usage.
*
* @param fileIdentifier the file to update (must be a file that already
* exists, required)
* @return a mutable presentation (never null)
*/
MutableFile updateFile(String fileIdentifier);
}