package com.ctp.cdi.query.home; import static com.ctp.cdi.query.home.EntityMessage.HomeOperation.CREATE; import static com.ctp.cdi.query.home.EntityMessage.HomeOperation.DELETE; import static com.ctp.cdi.query.home.EntityMessage.HomeOperation.UPDATE; import java.io.Serializable; import java.util.Collections; import java.util.LinkedList; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.persistence.metamodel.SingularAttribute; import com.ctp.cdi.query.EntityDao; public abstract class EntityHome<E, PK extends Serializable> implements Serializable { private static final long serialVersionUID = 1L; private static final int DEFAULT_PAGE_SIZE = 10; private PK id; private E entity; private Class<E> entityClass; private @Inject NavigationProvider navigation; private @Inject ConversationProvider conversation; private @Inject Event<EntityMessage> event; private @Inject PersistenceUtils<E, PK> utils; private E search; private int page; private int pageSize = DEFAULT_PAGE_SIZE; private long count; private List<E> pageItems; public Object create() { conversation.begin(); return navigation.create(); } public void retrieve() { if (navigation.isPostback()) { return; } if (conversation.isTransient()) { conversation.begin(); } if (id == null) { entity = this.search; } else { entity = getEntityDao().findBy(getId()); } } public Object update() { conversation.end(); try { getEntityDao().save(entity); if (id == null) { event.fire(EntityMessage.created(entity)); return navigation.search(); } else { event.fire(EntityMessage.updated(entity)); PK entityId = utils.primaryKeyValue(entity); return navigation.view(entityId); } } catch (Exception e) { event.fire(EntityMessage.failed(entity, id == null ? CREATE : UPDATE, e)); return navigation.exception(); } } public Object delete() { conversation.end(); try { getEntityDao().remove(getEntityDao().findBy(getId())); getEntityDao().flush(); return navigation.search(); } catch (Exception e) { event.fire(EntityMessage.failed(entity, DELETE, e)); return navigation.exception(); } } public void search() { this.page = 0; } @SuppressWarnings("unchecked") public void paginate() { List<SingularAttribute<E, ?>> attributes = searchAttributes(); if (attributes == null) { attributes = Collections.emptyList(); } SingularAttribute<E, Object>[] attArray = attributes.toArray(new SingularAttribute[attributes.size()]); count = getEntityDao().countLike(search, attArray); pageItems = getEntityDao().findByLike(search, page * pageSize, pageSize, attArray); } protected abstract EntityDao<E, PK> getEntityDao(); protected abstract List<SingularAttribute<E, ?>> searchAttributes(); @PostConstruct protected void init() { try { entityClass = utils.entityClass(getClass()); search = entityClass.newInstance(); } catch (Exception e) { throw new RuntimeException("Failed initializing EntityHome", e); } } protected SingularAttributes<E> singularAttributes() { return new SingularAttributes<E>(); } protected static class SingularAttributes<E> { private final List<SingularAttribute<E, ?>> attributes = new LinkedList<SingularAttribute<E,?>>(); public SingularAttributes<E> add(Object value, SingularAttribute<E, ?> attribute) { attributes.add(attribute); return this; } public SingularAttributes<E> addIfNotEmpty(Object value, SingularAttribute<E, ?> attribute) { if (value instanceof String && isNotEmpty((String) value)) { attributes.add(attribute); } else if (value != null) { attributes.add(attribute); } return this; } private boolean isNotEmpty(String value) { return value != null && !"".equals(value); } public List<SingularAttribute<E, ?>> getAttributes() { return attributes; } } // ------------------------------------------------------------------------ // ACCESSORS AND MUTATORS // ------------------------------------------------------------------------ public PK getId() { return id; } public void setId(PK id) { this.id = id; } public E getEntity() { return entity; } public void setEntity(E entity) { this.entity = entity; } public int getPage() { return page; } public void setPage(int page) { this.page = page; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public E getSearch() { return search; } public void setSearch(E search) { this.search = search; } public long getCount() { return count; } public List<E> getPageItems() { return pageItems; } }