001/**
002 *   GRANITE DATA SERVICES
003 *   Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S.
004 *
005 *   This file is part of the Granite Data Services Platform.
006 *
007 *   Granite Data Services is free software; you can redistribute it and/or
008 *   modify it under the terms of the GNU Lesser General Public
009 *   License as published by the Free Software Foundation; either
010 *   version 2.1 of the License, or (at your option) any later version.
011 *
012 *   Granite Data Services is distributed in the hope that it will be useful,
013 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
014 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
015 *   General Public License for more details.
016 *
017 *   You should have received a copy of the GNU Lesser General Public
018 *   License along with this library; if not, write to the Free Software
019 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
020 *   USA, or see <http://www.gnu.org/licenses/>.
021 */
022package org.granite.tide.spring.data;
023
024import java.io.Serializable;
025import java.util.Map;
026
027import javax.persistence.EntityManager;
028import javax.persistence.metamodel.ManagedType;
029
030import org.springframework.data.domain.Page;
031import org.springframework.data.domain.Pageable;
032import org.springframework.data.jpa.domain.Specification;
033import org.springframework.data.jpa.repository.support.JpaEntityInformation;
034import org.springframework.data.jpa.repository.support.JpaEntityInformationSupport;
035import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
036
037
038public class FilterableJpaRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements FilterableJpaRepository<T, ID> {
039
040        private JpaEntityInformation<T, ?> entityInformation;
041        private EntityManager entityManager;
042
043        public FilterableJpaRepositoryImpl(Class<T> domainClass, EntityManager entityManager) {
044                super(domainClass, entityManager);
045                
046                this.entityInformation = JpaEntityInformationSupport.getMetadata(domainClass, entityManager);
047            this.entityManager = entityManager;
048        }
049        
050        @SuppressWarnings("unchecked")
051        public Page<T> findByFilter(Object filter, Pageable pageable) {
052                if (filter == null)
053                        return findAll(pageable);
054                
055                ManagedType<?> filterType = entityManager.getMetamodel().managedType(entityInformation.getJavaType());            
056                Specification<T> specification = null;
057                
058                if (filter.getClass().equals(filterType.getJavaType()))
059                        specification = FilterExampleSpecification.byExample(entityManager.getMetamodel(), filter);             
060                else if (filter instanceof Map<?, ?>)
061                        specification = FilterMapSpecification.byMap((Map<String, Object>)filter);
062                else
063                        specification = FilterBeanSpecification.byBean(filter);
064                
065                return findAll(specification, pageable);
066        }
067}