package org.jboss.seam.example.seambay;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import javax.persistence.EntityManager;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.annotations.datamodel.DataModelSelection;
@Name("auctionSearch")
@Scope(ScopeType.SESSION)
public class AuctionSearchAction implements Serializable
{
private static final long serialVersionUID = -3548004575336733926L;
@In
EntityManager entityManager;
private int pageSize = 10;
private int page = 0;
private String searchTerm;
private Category searchCategory;
private boolean titleAndDescription;
@DataModel
private List<Auction> auctions;
@DataModelSelection
private Auction selectedAuction;
private Map<Category,Long> searchCategories = new HashMap<Category,Long>();
@SuppressWarnings("unchecked")
public void queryAuctions()
{
StringBuilder qry = new StringBuilder();
qry.append("from Auction a where a.status = 1 and endDate >= #{currentDatetime}");
if (titleAndDescription)
{
qry.append(" and (lower(title) like #{searchPattern} or lower(description) like #{searchPattern})");
}
else
{
qry.append(" and lower(title) like #{searchPattern}");
}
if (searchCategory != null)
{
qry.append(" and a.category in (#{subCategories})");
}
auctions = entityManager.createQuery(qry.toString())
.setMaxResults(pageSize)
.setFirstResult( page * pageSize )
.getResultList();
searchCategories.clear();
StringBuilder catQuery = new StringBuilder();
catQuery.append("select a.category.categoryId, count(a) from Auction a " +
"where lower(a.title) like #{searchPattern} " +
"and a.endDate >= #{currentDatetime} and a.status = 1 ");
if (searchCategory != null)
{
catQuery.append("and a.category in (#{subCategories}) ");
}
catQuery.append("group by a.category.categoryId");
for (Object[] result : (List<Object[]>) entityManager.createQuery(
catQuery.toString()).getResultList())
{
searchCategories.put(entityManager.find(Category.class, result[0]), (Long) result[1]);
}
}
public void queryAllAuctions()
{
searchCategory = null;
queryAuctions();
}
@Factory(value="searchPattern", scope=ScopeType.EVENT)
public String getSearchPattern()
{
return searchTerm == null ?
"%" : '%' + searchTerm.toLowerCase().replace('*', '%') + '%';
}
public String getSearchTerm()
{
return searchTerm;
}
public void setSearchTerm(String searchTerm)
{
this.searchTerm = searchTerm;
}
public int getPageSize()
{
return pageSize;
}
public void setPageSize(int pageSize)
{
this.pageSize = pageSize;
}
public int getPage()
{
return page;
}
public void setPage(int page)
{
this.page = page;
}
public List<Entry> getSearchCategories()
{
List<Entry> cats = new ArrayList<Entry>(searchCategories.entrySet());
Collections.sort(cats, new Comparator<Entry>() {
public int compare(Entry e1, Entry e2) {
return ((Category) e1.getKey()).getName().compareToIgnoreCase(
((Category) e2.getKey()).getName());
}
});
return cats;
}
public void selectCategory(Category category)
{
setSearchCategory(category);
queryAuctions();
}
@Factory(value="subCategories", scope=ScopeType.EVENT)
public Set<Category> getSubCategories()
{
Set<Category> categories = new HashSet<Category>();
categories.add(searchCategory);
addSubCategories(searchCategory, categories);
return categories;
}
@SuppressWarnings("unchecked")
private void addSubCategories(Category parent, Set<Category> categories)
{
List<Category> children = entityManager.createQuery(
"from Category where parent = :parent")
.setParameter("parent", parent)
.getResultList();
for (Category child : children)
{
categories.add(child);
addSubCategories(child, categories);
}
}
public Category getSearchCategory()
{
return searchCategory;
}
public List<Auction> getAuctions()
{
return auctions;
}
public void setSearchCategory(Category category)
{
this.searchCategory = category;
}
public Integer getSelectedCategoryId()
{
return searchCategory != null ? searchCategory.getCategoryId() : null;
}
public void setSelectedCategoryId(Integer categoryId)
{
this.searchCategory = entityManager.find(Category.class, categoryId);
}
public boolean isTitleAndDescription()
{
return titleAndDescription;
}
public void setTitleAndDescription(boolean value)
{
this.titleAndDescription = value;
}
}