package org.ovirt.engine.core.builder;
/**
* Base for builders to create domain objects. Builders extending this builder allow building and peristing objects. The
* builders are only meant for unit- and integration testing purposes.
* <p>
* Use the following methods to create an entity with the builder:
* <p>
* * {@link #persist()} to persist the built object in a real database. This is very useful when running integration
* tests with an available database.
* <p>
* * {@link #build()} to just build the objects and return them. This is very useful when writing unit tests. No
* database needs to be present and no DAOs are involved.
* <p>
* The builder will always return the same instance when the builder is not explicitly reset. This allows persisting
* many instances by just changing the {@link org.ovirt.engine.core.compat.Guid} of an object.
* <p>
* Use the following methods to reset the builder:
* <p>
* * {@link #reset()} reset the whole builder to its original state.
* <p>
* * {@link #reset(T object)} resets the whole builder to its original state and sets the supplied argument as the
* template to use.
* <p>
* <b>Examples</b>
* <p>
* Add a running VM to a host, persist everything to the database and load all VMs which are running on the
* host:
* <pre>{@code
* VDS host = vdsBuilder.cluster(persistedCluster).persist();
* vmBuilder.host(host).up().persist();
* List<VM> vms = vmDao.getAllRunningForVds(host.getId());
* }</pre>
* Add 10 hosts with 1 GB of RAM to a cluster, persist the hosts to the database and load them again:
* <pre>{@code
* VdsBuilder builder = new VdsBuilder().cluster(persistedCluster).physicalMemory(1000);
* for (int x =0; x < 10; x++){
* builder.id(Guid.newGuid()).persist();
* }
* List<Vds> persistedHosts = vdsDao.getAllForCluster(persistedCluster.getId());
* }</pre>
*/
public abstract class AbstractBuilder<T, B extends AbstractBuilder> {
public AbstractBuilder() {
reset();
}
protected T object;
/**
* Reset the builder into its original state.
*
* @return the scrubbed builder
*/
public abstract B reset();
/**
* Reset the builder into its original state and set the provided object as a template.
*
* @param object the template
* @return the builder
*/
public abstract B reset(T object);
/**
* Hook to check if all default values are set when building an object with {@link #build()}. Validation and setting
* default values if they are missing can be done here.
*/
protected void preBuild() {
}
/**
* Hook to change the way on how to finally build the desired object. The default implementation just returns
* the {@link AbstractBuilder#object}. An alternative implementation might do a shallow or deep copy on every
* invocation.
* @return the created object
*/
protected T doBuild() {
return object;
}
/**
* Hook to check if all default values are set when building an object with {@link #persist()}. Validation and
* setting default values if they are missing can be done here.
*/
protected abstract void prePersist();
/**
* Persist the object in the database and return the persisted object.
* <p>
* Subsequent calls to persist without resetting an object or setting another id can lead to constraint violations
* in the database.
*
* @return the persisted object
*/
protected abstract T doPersist();
public final T build() {
preBuild();
return doBuild();
}
public final T persist() {
prePersist();
return doPersist();
}
}