Zest™
Introduction
Tutorials
Javadoc
Samples
Core
Libraries
Extensions
Tools
Glossary 

UoWFile

code

docs

tests

The UoWFile Library provides an easy way to bind file operations to UnitOfWorks.

In other words, using this library you can easily attach files to your Composites, mostly EntityComposites, so that if the UoW gets discarded, changes to files are discarded too. Concurrent modifications are properly handled.

Note that it has a performance impact relative to the files size as it duplicates the file to keep a backup for eventual rollback. However, the API provides a way to get non-managed handles on the attached files to keep your read-only operations fast.

The location of files is left to the developer using a private mixin.

Table 54. Artifact

Group IDArtifact IDVersion

org.qi4j.library

org.qi4j.library.uowfile

2.1


Logging

The SLF4J Logger used by this library is named "org.qi4j.library.uowfile".

Add an attached file to an Entity

Let’s say you have the following Entity:

public interface TestedEntity
  [...snip...]

{
    Property<String> name();
}

To add an attached file to it you first need to extends HasUoWFileLifecycle:

public interface TestedEntity
    , Identity
{
    Property<String> name();
}

This provides you with the following contract:

public interface HasUoWFile
{
    /**
     * IMPORTANT Use this {@link File} inside read-only {@link UnitOfWork}s only
     * @return The file that is attached.
     */
    File attachedFile();

    File managedFile();
      [...snip...]


}

Next you need to write the UoWFileLocator mixin:

public static class TestedFileLocatorMixin
    implements UoWFileLocator
{
    @This
    private Identity meAsIdentity;

    @Override
    public File locateAttachedFile()
    {
        return new File( baseTestDir, meAsIdentity.identity().get() );
    }
}

Assemble all this as follow:

public void assemble( ModuleAssembly module )
    throws AssemblyException
{
    new UoWFileAssembler().assemble( module );

    module.entities( TestedEntity.class ).withMixins( TestedFileLocatorMixin.class );
      [...snip...]

}

You can now use the following methods on your EntityComposite:

File attachedFile = entity.attachedFile();
File managedFile = entity.managedFile();

Going plural

Now if you want to attach several files to one entity, this library provides a simple mechanism allowing you to use any enum as discriminator.

Let’s say you have the following Entity:

public interface TestedEntity
  [...snip...]

{
    Property<String> name();
}

It’s the very same as the one used to start the singular file support described above.

To add an attached file to it you first need to write an enum and extends HasUoWFilesLifecycle:

public enum MyEnum
{
    fileOne, fileTwo
}

public interface TestedEntity
    , Identity
{
    Property<String> name();
}

This provides you with the following contract:

public interface HasUoWFiles<T extends Enum<T>>
{
    /**
     * IMPORTANT Use this {@link File} only inside read-only {@link UnitOfWork}s
     */
    File attachedFile( T key );

    /**
     * IMPORTANT Use these {@link File}s only inside read-only {@link UnitOfWork}s
     */
    Iterable<File> attachedFiles();

    File managedFile( T key );

    Iterable<File> managedFiles();
      [...snip...]

}

Next you need to write the UoWFileLocator mixin:

public static abstract class TestedFilesLocatorMixin
    implements UoWFilesLocator<MyEnum>
{
    @This
    private Identity meAsIdentity;

    @Override
    public Iterable<File> locateAttachedFiles()
    {
        List<File> list = new ArrayList<>();
        for( MyEnum eachValue : MyEnum.values() )
        {
            list.add( new File( baseTestDir, meAsIdentity.identity().get() + "." + eachValue.name() ) );
        }
        return list;
    }

    @Override
    public File locateAttachedFile( MyEnum key )
    {
        return new File( baseTestDir, meAsIdentity.identity().get() + "." + key.name() );
    }
}

Assemble all this as follow:

public void assemble( ModuleAssembly module )
    throws AssemblyException
{
    new UoWFileAssembler().assemble( module );

    module.entities( TestedEntity.class ).withMixins( TestedFilesLocatorMixin.class );
      [...snip...]

}

You can now use the following methods on your EntityComposite:

File attachedFileTwo = entity.attachedFile( MyEnum.fileTwo );
File managedFileOne = entity.managedFile( MyEnum.fileOne );