001/* 002 GRANITE DATA SERVICES 003 Copyright (C) 2011 GRANITE DATA SERVICES S.A.S. 004 005 This file is part of Granite Data Services. 006 007 Granite Data Services is free software; you can redistribute it and/or modify 008 it under the terms of the GNU Library General Public License as published by 009 the Free Software Foundation; either version 2 of the License, or (at your 010 option) any later version. 011 012 Granite Data Services is distributed in the hope that it will be useful, but 013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License 015 for more details. 016 017 You should have received a copy of the GNU Library General Public License 018 along with this library; if not, see <http://www.gnu.org/licenses/>. 019*/ 020 021package org.granite.spring.data; 022 023import java.lang.reflect.Field; 024import java.lang.reflect.Type; 025import java.util.ArrayList; 026import java.util.List; 027 028import org.granite.messaging.amf.io.convert.Converter; 029import org.granite.messaging.amf.io.convert.Converters; 030import org.granite.messaging.amf.io.convert.Reverter; 031import org.granite.tide.data.model.PageInfo; 032import org.granite.tide.data.model.SortInfo; 033import org.springframework.data.domain.Page; 034import org.springframework.data.domain.Pageable; 035import org.springframework.data.domain.Sort; 036import org.springframework.data.domain.Sort.Direction; 037import org.springframework.data.domain.Sort.Order; 038 039 040public class PageableConverter extends Converter implements Reverter { 041 042 public PageableConverter(Converters converters) { 043 super(converters); 044 } 045 046 @Override 047 protected boolean internalCanConvert(Object value, Type targetType) { 048 return (value instanceof PageInfo && targetType.equals(Pageable.class)) 049 || (value instanceof SortInfo && targetType.equals(Sort.class)); 050 } 051 052 @Override 053 protected Object internalConvert(Object value, Type targetType) { 054 if (targetType.equals(Pageable.class)) { 055 PageInfo pageInfo = (PageInfo)value; 056 Sort sort = null; 057 if (pageInfo.getSortInfo() != null && pageInfo.getSortInfo().getOrder() != null && pageInfo.getSortInfo().getOrder().length > 0) { 058 List<Order> orders = new ArrayList<Order>(pageInfo.getSortInfo().getOrder().length); 059 for (int i = 0; i < pageInfo.getSortInfo().getOrder().length; i++) 060 orders.add(new Order(pageInfo.getSortInfo().getDesc()[i] ? Direction.DESC : Direction.ASC, pageInfo.getSortInfo().getOrder()[i])); 061 sort = new Sort(orders); 062 } 063 return new PageRequest(pageInfo.getFirstResult(), pageInfo.getMaxResults(), sort); 064 } 065 return null; 066 } 067 068 public boolean canRevert(Object value) { 069 return value instanceof Page; 070 } 071 072 public Object revert(Object value) { 073 @SuppressWarnings("unchecked") 074 Page<Object> page = (Page<Object>)value; 075 int offset = page.getNumber() * page.getSize(); 076 try { 077 Field f = page.getClass().getDeclaredField("pageable"); 078 f.setAccessible(true); 079 Pageable pageable = (Pageable)f.get(page); 080 offset = pageable.getOffset(); 081 } 082 catch (Exception e) { 083 } 084 return new org.granite.tide.data.model.Page<Object>(offset, page.getSize(), Long.valueOf(page.getTotalElements()).intValue(), page.getContent()); 085 } 086 087 088 public static class PageRequest implements Pageable { 089 090 private int offset; 091 private int pageSize; 092 private Sort sort; 093 094 public PageRequest(int offset, int pageSize, Sort sort) { 095 this.offset = offset; 096 this.pageSize = pageSize; 097 this.sort = sort; 098 } 099 100 public int getOffset() { 101 return offset; 102 } 103 104 public int getPageNumber() { 105 return pageSize > 0 ? offset / pageSize : 0; 106 } 107 108 public int getPageSize() { 109 return pageSize; 110 } 111 112 public Sort getSort() { 113 return sort; 114 } 115 } 116}