Table of Contents
Schmant uses EntityFS extensively for working with files and directories. This appendix gives some basic information about EntityFS programming that might be useful for build script writers. More exhaustive information about EntityFS programming can be found in the EntityFS Programmer's Guide.
EntityFS is an object-oriented file system API for Java. The difference in philosophy between EntityFS and Java's built in file and directory support is that Java's File object represents a path in the local file system, while EntityFS entities represent the files and directories themselves. From the application's perspective, an EntityFS EFile entity, for instance, can be said to be the file, while a Java File object is a pointer to the file. If the EntityFS EFile is moved, the object is updated with the new location. If it is deleted, the entity object is invalidated. If a new file is put in the same location in the file system, the original EFile object is still invalid.
The properties of entity objects are further discussed in this article on the EntityFS site.
EntityFS file systems can be built on the operating system's file system, on Zip or Jar files or in memory. See for instance the section called “In-memory file systems”.
An EntityFS FileSystem contains file and directory entities. Entities are mostly used through any of the utility classes.
The EntityFS Programmer's Guide contains an appendix
on how to move from EntityFS classes to java.io
classes and back again. See also
Example 5.3, “From Java files to EntityFS and back again”.
The SchmantFileSystems utility class contains
the makeFileBacked
and
makeRandomlyAccessible
methods for making
EFile entities File-backed and
FCRandomAccess:ible, respectively.
Entities always live within the context of a FileSystem. It has some global properties, such as strategies for entity locking and for handling of file system events. It can also have any number of FileSystemCapability:s and EntityCapability:s that extend its functionality. For instance, the ECFileResolvable entity capability makes files and directories resolvable to Java's File objects.
A file system always contains a root Directory that can
be retrieved by calling its getRootDirectory()
method.
File systems are either created manually using a FileSystemBuilder or through any of the utility methods of SchmantFileSystems. SchmantFileSystems adapts the file system-creating methods of EntityFS' FileSystems and also adds a few file system-creation methods of its own.
FileSystem:s may be created to support entity locking. This should be enabled for all read/write file systems accessed by parallel build threads, since it prevents tasks from accidentally writing to the same files or directories simultaneously. Many of the file systems returned by SchmantFileSystems' methods have locking enabled.
Table B.1. FileSystemBuilder implementations
Implementation | Description |
---|---|
FSROFileSystemBuilder | Builds a read only file system that is backed by the operating system's file system. The file system's root directory can be in any directory in the backing file system. |
FSRWFileSystemBuilder | Builds a read/write file system that is backed by the operating system's file system. The file system's root directory can be in any directory in the backing file system. |
JarFileSystemBuilder | Builds a read only file system that is backed by a Jar file. The root directory is in the root of the Jar file. |
RamFileSystemBuilder | Builds a read/write file system that stores its data in memory. |
ZipFileSystemBuilder | Builds a read only file system that is backed by a Zip file. The root directory is in the root of the Zip file. |
Schmant implements a LogAdapter,
the SchmantReportLogAdapter, for making EntityFS log
into a Schmant Report. This log adapter can manually be set
on a file system fs
by calling
fs.getLogAdapterHolder().setLogAdapter(SchmantReportLogAdapter.INSTANCE)
.
If any of the methods of SchmantFileSystems or
TempFileUtil are used
for creating entities (and thus also file systems), the returned file systems
already have the Schmant log adapter set.
Entity:s live within the context of a FileSystem; an entity can never leave it. Every entity has a unique location, an AbsoluteLocation in its file system.
Entity objects are never instantiated directly by clients. Existing entities are retrieved from their parent Directory object or, more commonly, by using the utility methods of Directories. New entities are also created by using the methods of their parent Directory or by using Directories' methods.
All entities use read/write locking to protect them from concurrent modification. Before using an entity method on an entity in a locking file system, the entity has to be either locked for reading or writing, depending on what the method does. All utility class methods acquire the necessary locks before calling entity methods, which make them much easier to use compared with calling entity methods directly.
A DirectoryView is a Directory viewed through zero or more EntityFilter:s. If a child directory is fetched through a directory view, it inherits the parent directory's view settings.
A common usage is to use directory views to hide all
.svn
directories in a file system, see
this example.
Often, most of the work against a FileSystem and its entities is done through EntityFS' utility classes. They have high-level methods for common operations, such as listing directory contents with filters or reading contents of files.
Table B.2. EntityFS utility classes (useful subset)
Utility class | Utility methods for |
---|---|
Directories | Working with Directory:s. |
ECFileResolvableUtil | Entities that can be resolvable to Java's File objects. |
ECJarEntryUtil | Entities in a Jar file. |
ECUriResolvableUtil | Entities that can be resolvable to Java's URI:s. |
Directories | Working with Directory:s. |
ECZipEntryUtil | Entities in a Zip or Jar file. |
Entities | Working with entities (files or directories). |
EntityFilters | Working with EntityFilter:s. |
FCFileBackedUtil | Working with file entities that can be resolved to Java's File objects. |
Files | Working with EFile:s. |
FileSystems | Working with FileSystem:s. |
FSCFileResolvableUtil | Working with file systems whose entities can be resolved to Java's File objects. |
FSCUriResolvableUtil | Working with file systems whose entities can be resolved to Java's URI objects. |
Iterators | Working with Iterator:s. |
PropertiesUtil | Loading EntityFS Properties. |
StreamUtil | Working with streams and channels. |
The following table contains the entity Filter implementations that EntityFS comes with.
Table B.3. EntityFilter implementations
Implementation | Description |
---|---|
DirectoryEmptyFilter | Matches empty directories. |
DirectoryFilter | Matches directories. |
EFileFilter | Matches files. |
EFileNameExtensionFilter | Matches files whose names have one of a set of extensions. |
EntityIdentityFilter | Matches a specific entity instance. |
EntityLatestModificationTimeFilter | Matches entities that were modified before a specific time. |
EntityLocationGlobFilter | Matches entities whose location relative to a base directory matches a glob pattern. |
EntityLocationRegexpFilter | Matches entities whose location relative to a base directory matches a regular expression pattern. |
EntityNameFilter | Matches entities with a specific name. |
EntityNameGlobFilter | Matches entities whose names match a glob pattern. |
EntityNamePrefixFilter | Matches entities whose names start with a specific prefix. |
EntityNameRegexpFilter | Matches entities whose names match a regular expression pattern. |
EntityRecentModificationFilter | Matches entities that have been modified within a specified time limit. |
EntityTypeFilter | Matches entities of a specific type (files or directories). It is better to use EFileFilter or DirectoryFilter instead. |
FalseFilter | Does not match any entity. |
LockedEntityFilter | Matches entities that are locked for reading or writing by the current thread. |
ParentFilter | Matches entities that have a specific parent directory. |
ReadLockedEntityFilter | Matches entities that are locked for reading by the current thread. |
SuperParentAndFilter | Matches an entity if all of its parent directories match another filter. |
SuperParentAndFilter | Matches an entity if any of its parent directories match another filter. |
TrueFilter | Matches all entities. |
WriteLockedEntityFilter | Matches entities that are locked for writing by the current thread. |
All entity filters implement ConvenientFilter
so they have and
, or
,
xor
and not
methods to combine them with other filters.
See for instance this example for how filters can be used.
The following is a collection of best practices for using EntityFS in Schmant build scripts:
If possible, use SchmantFileSystems methods instead of FileSystemBuilder:s for creating file systems. The file systems created by SchmantFileSystems are configured with settings that work well with build scripts.
Create a read only file system for the build's source files and a read/write file system for the build's target directories. See Example B.1, “Creating source and target file systems”.