A Repository stores objects of type T. The term Home in Arena stands for a place where objects live.
T must be a subclass of Entity, which defines the following behavior:
a unique identifier (property id)
hashCode() and equals() method are based on id property
isNew() message to identify new objects
template methods validateCreate() and validateDelete() you can override to add validations
create: adds an object to that repository, so it can be retrieved afterwards
delete: removes an object
update: modify an object in position x or remove old object/add a new one in position x
different kinds of search. Arena provides
org.uqbar.commons.model.CollectionBasedRepo
It is a memory-based collection, without persistence capabilities. Once application is closed, all data is lost. It is intended for educational purposes, or in developments where persistence is not mandatory (like games).
Arena Persistence defines an abstract class PersistentRepo that persists data into a Neo4J graph database.
Add the following dependency in your pom.xml
<dependency> <groupId>org.uqbar-project</groupId> <artifactId>arena-pers</artifactId> <version>3.6.1</version> </dependency>
And check out this examples:
it is usually defined as a Singleton, because we want to provide a global point of access, so all updates and retrieves are centralized. You can use an Application context object to configure different homes for testing and runtime environments.
you can simply define your own Repository implementation, or subclass any available implementation
it is recommended to create a fixture or data set
you can define your own search() method, or use a searchByExample() implementing getCriterio() method
methods you must override
Example of a Repository for Customers defining a special search.
// Java @Override public Class<Celular> getEntityType() { return Customer.class; } @Override public Celular createExample() { return new Customer(); } // Xtend override def getEntityType() { typeof(Customer) } override def createExample() { new Customer }
Defining a criteria for a search by example:
override def Predicate<Customer> getCriterio(Customer example) { var result = this.allCriteria if (example.number != null) { result = new AndPredicate(result, this.getCriteriaByNumber(example.number)) } if (example.name != null) { result = new AndPredicate(result, this.getCriteriaByName(example.name)) } result } override getAllCriteria() { [ Customer customer | true ] as Predicate<Customer> } def getCriteriaByNumber(Integer number) { [ Customer customer | customer.number.equals(number) ] as Predicate<Customer> } def getCriteriaByName(String name) { [ Customer customer | customer.name.toLowerCase.contains(name.toLowerCase) ] as Predicate<Customer> }
Defining an ad-hoc search method:
def search(Integer number, String name) { allInstances.filter [customer | this.match(number, customer.number) && this.match(name, customer.name)].toList }
Note that if you are using a persistent implementation, this is not a good idea, since you are bringing all database into memory before filtering elements.
You can create the data
in an init() method of a repository object
or you can use Arena Bootstrap interface, to decouple data initialization from create / retrieve / update / delete methods.
// Xtend class CelularesBootstrap extends CollectionBasedBootstrap { /** * Inits cellphone models repository outside its definition * as a decoupling strategy */ override run() { val repoModels = RepoModels.instance ... val nokiaAsha = repoModels.create("NOKIA ASHA 501", 700f, true) val lgOptimusL5 = repoModels.create("LG OPTIMUS L5 II", 920f, false) ...
isPending() method indicates whether run() method should be executed:
(usually from an Application Model or Panel)
You can fire a search-by-example
// Java Cellphone searchedCellphone = new Cellphone(number, name); List<Celular> results = repoCellPhones.searchByExample(searchedCellphone); // Xtend val searchedCellphone = new Cellphone => [ number = _number name = _name ] results = repoCellphones.searchByExample(searchedCellphone)
or a direct search:
// Java List<Cellphone> results = repoCellphones.search(number, name); // Xtend results = repoCellphones.search(number, name)
Updating / creating an object example:
// Java if (getModelObject().isNew()) { getRepoCellphones().create(getModelObject()); } else { getRepoCellphones().update(getModelObject()); } // Xtend if (modelObject.isNew) { repoCellphones.create(modelObject) } else { repoCellphones.update(modelObject) }