/* * Copyright (c) 2009 Mysema Ltd. * All rights reserved. * */ package com.mysema.rdfbean.tapestry; import java.util.List; import javax.annotation.Nullable; import org.apache.tapestry5.grid.GridDataSource; import org.apache.tapestry5.grid.SortConstraint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.mysema.commons.lang.Assert; import com.mysema.query.types.EntityPath; import com.mysema.query.types.OrderSpecifier; import com.mysema.query.types.Predicate; import com.mysema.query.types.expr.ComparableExpression; import com.mysema.query.types.path.PathBuilder; import com.mysema.rdfbean.object.BeanQuery; import com.mysema.rdfbean.object.Session; import com.mysema.rdfbean.object.SessionCallback; import com.mysema.rdfbean.object.SessionFactory; /** * BeanGridDataSource provides an implementation of the GridDataSource interface * for RDFBean * * @author tiwe */ public class BeanGridDataSource<T> implements GridDataSource { private static final Logger logger = LoggerFactory.getLogger(BeanGridDataSource.class); private final SessionFactory sessionFactory; private final Class<T> entityType; private final PathBuilder<T> entityPath; private int startIndex; private List<T> preparedResults; @Nullable private final Predicate conditions; private final OrderSpecifier<?> defaultOrder; private final boolean caseSensitive; /** * Create a new BeanGridDataSource instance with no filter conditions * * @param sessionFactory * @param entity * root entity of the query * @param defaultOrder * default order for queries, if no order is specified * @param caseSensitive * case sensitive ordering */ public BeanGridDataSource(SessionFactory sessionFactory, EntityPath<T> entity, OrderSpecifier<?> defaultOrder, boolean caseSensitive) { this(sessionFactory, entity, defaultOrder, caseSensitive, null); } /** * Create a new BeanGridDataSource instance with filter conditions * * @param sessionFactory * @param entity * root entity of the query * @param defaultOrder * default order for queries, if no order is specified * @param caseSensitive * case sensitive ordering * @param conditions * filter conditions */ @SuppressWarnings("unchecked") public BeanGridDataSource(SessionFactory sessionFactory, EntityPath<T> entity, OrderSpecifier<?> defaultOrder, boolean caseSensitive, @Nullable Predicate conditions) { this.sessionFactory = Assert.notNull(sessionFactory, "sessionFactory"); this.entityType = (Class<T>) Assert.notNull(entity.getType(), "entity has no type"); this.entityPath = new PathBuilder<T>(entity.getType(), entity.getMetadata()); this.defaultOrder = Assert.notNull(defaultOrder, "defaultOrder"); this.conditions = conditions; this.caseSensitive = caseSensitive; } @Override public int getAvailableRows() { return sessionFactory.execute(new SessionCallback<Integer>() { @Override public Integer doInSession(Session session) { BeanQuery beanQuery = session.from(entityPath); if (conditions != null) { beanQuery.where(conditions); } return (int) beanQuery.count(); } }); } @Override public void prepare(final int start, final int end, final List<SortConstraint> sortConstraints) { Assert.notNull(sortConstraints, "sortContraints"); sessionFactory.execute(new SessionCallback<Void>() { @Override public Void doInSession(Session session) { prepare(session, start, end, sortConstraints); return null; } }); } @SuppressWarnings("unchecked") private void prepare(Session session, int startIndex, int endIndex, List<SortConstraint> sortConstraints) { BeanQuery beanQuery = session.from(entityPath); beanQuery.offset(startIndex); beanQuery.limit(endIndex - startIndex + 1); if (sortConstraints.isEmpty()) { beanQuery.orderBy(defaultOrder); } for (SortConstraint constraint : sortConstraints) { String propertyName = constraint.getPropertyModel().getPropertyName(); Class<? extends Comparable<?>> propertyType = constraint.getPropertyModel().getPropertyType(); ComparableExpression<?> propertyPath; if (!caseSensitive && propertyType.equals(String.class)) { propertyPath = entityPath.getString(propertyName).toLowerCase(); } else { propertyPath = entityPath.getComparable(propertyName, propertyType); } switch (constraint.getColumnSort()) { case ASCENDING: beanQuery.orderBy(propertyPath.asc()); break; case DESCENDING: beanQuery.orderBy(propertyPath.desc()); break; } } if (conditions != null) { beanQuery.where(conditions); } this.startIndex = startIndex; preparedResults = beanQuery.list(entityPath); } @Override public Object getRowValue(int index) { index = index - startIndex; if (index < preparedResults.size()) { return preparedResults.get(index); } else { logger.error("Invalid index " + index + " (size " + preparedResults.size() + ")"); return null; } } @Override public Class<?> getRowType() { return entityType; } }