KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jasperreports > engine > data > JRJpaDataSource


1 /*
2  * ============================================================================
3  * GNU Lesser General Public License
4  * ============================================================================
5  *
6  * JasperReports - Free Java report-generating library.
7  * Copyright (C) 2001-2005 JasperSoft Corporation http://www.jaspersoft.com
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  *
23  * JasperSoft Corporation
24  * 303 Second Street, Suite 450 North
25  * San Francisco, CA 94107
26  * http://www.jaspersoft.com
27  */

28 package net.sf.jasperreports.engine.data;
29
30 import java.util.HashMap JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.Map JavaDoc;
34
35 import net.sf.jasperreports.engine.JRException;
36 import net.sf.jasperreports.engine.JRField;
37 import net.sf.jasperreports.engine.JRRewindableDataSource;
38 import net.sf.jasperreports.engine.JRRuntimeException;
39 import net.sf.jasperreports.engine.query.JRJpaQueryExecuter;
40
41 /**
42  * Java Persistence API data source that uses <code>javax.persistence.Query.getResultList()</code>.
43  * <p/>
44  * The query result can be paginated by not retrieving all the rows at once.
45  * <p/>
46  * Fields are mapped to values in the result following these rules:
47  * <ul>
48  * <li>if the query returns a single object/bean (e.g. <code>SELECT m FROM Movie m</code> or
49  * <code>SELECT NEW MovieDescription(m.title, m.genre) FROM Movie m</code>), then the fields are
50  * mapped to bean property names.</li>
51  * <li>if the query returns multiple objects per row (e.g. <code>SELECT m.title, m.gender FROM Movie m</code>),
52  * the fields are mapped using the following syntax: COLUMN_<em>index</em>[.<em>property</em>], with the
53  * indexes starting from 1. Example mappings: COLUMN_1, COLUMN_2, COLUMN_2.title, COLUMN_2.movie.title.</li>
54  * </ul>
55  *
56  * @author Marcel Overdijk (marceloverdijk@hotmail.com)
57  * @version $Id: JRJpaDataSource.java 1303 2006-06-16 13:39:43 +0300 (Fri, 16 Jun 2006) lucianc $
58  * @see net.sf.jasperreports.engine.query.JRJpaQueryExecuterFactory#PROPERTY_JPA_QUERY_PAGE_SIZE
59  */

60 public class JRJpaDataSource extends JRAbstractBeanDataSource implements JRRewindableDataSource {
61     private static final String JavaDoc MAPPING_INDEX_PREFIX = "COLUMN_";
62     private static final int MAPPING_INDEX_PREFIX_LENGTH = MAPPING_INDEX_PREFIX.length();
63     private static final String JavaDoc MAPPING_INDEX_PROPERTY_SEP = ".";
64     private static final int MAPPING_INDEX_PROPERTY_SEP_LENGTH = MAPPING_INDEX_PROPERTY_SEP.length();
65     
66     private final JRJpaQueryExecuter queryExecuter;
67     private final int pageSize;
68     private int pageCount;
69     private boolean nextPage;
70     private List JavaDoc returnValues;
71     private Iterator JavaDoc iterator;
72     protected Object JavaDoc currentRow;
73     private Map JavaDoc fieldValueReaders;
74
75     public JRJpaDataSource(JRJpaQueryExecuter queryExecuter, int pageSize) {
76         super(true);
77
78         this.queryExecuter = queryExecuter;
79         this.pageSize = pageSize;
80         
81         fieldValueReaders = new HashMap JavaDoc();
82         
83         pageCount = 0;
84         fetchPage();
85     }
86
87     protected void fetchPage() {
88         if (pageSize <= 0) {
89             returnValues = queryExecuter.getResultList();
90             nextPage = false;
91         }
92         else {
93             returnValues = queryExecuter.getResultList(pageCount * pageSize, pageSize);
94             nextPage = returnValues.size() == pageSize;
95         }
96
97         ++pageCount;
98
99         initIterator();
100     }
101
102     public boolean next() {
103         if (iterator == null) {
104             return false;
105         }
106         
107         boolean hasNext = iterator.hasNext();
108         if (!hasNext && nextPage) {
109             fetchPage();
110             hasNext = iterator != null && iterator.hasNext();
111         }
112         
113         if (hasNext) {
114             currentRow = iterator.next();
115         }
116
117         return hasNext;
118     }
119
120     public void moveFirst() {
121         if (pageCount == 1) {
122             initIterator();
123         }
124         else {
125             pageCount = 0;
126             fetchPage();
127         }
128     }
129
130     private void initIterator() {
131         iterator = returnValues == null ? null : returnValues.iterator();
132     }
133     
134     public Object JavaDoc getFieldValue(JRField field) throws JRException {
135         FieldValueReader reader = getFieldValueReader(field);
136         return reader.getValue();
137     }
138     
139     protected FieldValueReader getFieldValueReader(JRField field)
140     {
141         FieldValueReader reader = (FieldValueReader) fieldValueReaders.get(field.getName());
142         if (reader == null)
143         {
144             String JavaDoc mapping = getPropertyName(field);
145             reader = createReader(mapping);
146             fieldValueReaders.put(field.getName(), reader);
147         }
148         return reader;
149     }
150
151     private FieldValueReader createReader(String JavaDoc mapping)
152     {
153         FieldValueReader reader = null;
154         if (mapping.startsWith(MAPPING_INDEX_PREFIX))
155         {
156             int propertySepIdx = mapping.indexOf(MAPPING_INDEX_PROPERTY_SEP, MAPPING_INDEX_PREFIX_LENGTH + 1);
157             if (propertySepIdx < 0)
158             {
159                 String JavaDoc indexStr = mapping.substring(MAPPING_INDEX_PREFIX_LENGTH);
160                 try
161                 {
162                     int index = Integer.parseInt(indexStr);
163                     reader = new IndexReader(index - 1);
164                 }
165                 catch (NumberFormatException JavaDoc e)
166                 {
167                     //ignore
168
}
169             }
170             else
171             {
172                 String JavaDoc indexStr = mapping.substring(MAPPING_INDEX_PREFIX_LENGTH, propertySepIdx);
173                 try
174                 {
175                     int index = Integer.parseInt(indexStr);
176                     String JavaDoc property = mapping.substring(propertySepIdx + MAPPING_INDEX_PROPERTY_SEP_LENGTH);
177                     reader = new IndexPropertyReader(index - 1, property);
178                 }
179                 catch (NumberFormatException JavaDoc e)
180                 {
181                     //ignore
182
}
183             }
184         }
185
186         //default to a property mapping
187
if (reader == null)
188         {
189             reader = new PropertyReader(mapping);
190         }
191         
192         return reader;
193     }
194
195     protected static interface FieldValueReader
196     {
197         Object JavaDoc getValue() throws JRException;
198     }
199     
200     protected class PropertyReader implements FieldValueReader
201     {
202         private final String JavaDoc property;
203         
204         public PropertyReader(String JavaDoc property)
205         {
206             this.property = property;
207         }
208         
209         public Object JavaDoc getValue() throws JRException
210         {
211             return getBeanProperty(currentRow, property);
212         }
213     }
214     
215     protected class IndexReader implements FieldValueReader
216     {
217         private final int position;
218         
219         public IndexReader(int position)
220         {
221             this.position = position;
222         }
223         
224         public Object JavaDoc getValue() throws JRException
225         {
226             Object JavaDoc[] values = (Object JavaDoc[]) currentRow;
227             if (position < 0 || position >= values.length)
228             {
229                 throw new JRRuntimeException("Index " + position + " out of bounds for query result of lenght " + values.length);
230             }
231             return values[position];
232         }
233     }
234     
235     protected class IndexPropertyReader implements FieldValueReader
236     {
237         private final int position;
238         private final String JavaDoc property;
239         
240         public IndexPropertyReader(int position, String JavaDoc property)
241         {
242             this.position = position;
243             this.property = property;
244         }
245         
246         public Object JavaDoc getValue() throws JRException
247         {
248             Object JavaDoc[] values = (Object JavaDoc[]) currentRow;
249             if (position < 0 || position >= values.length)
250             {
251                 throw new JRRuntimeException("Index " + position + " out of bounds for query result of lenght " + values.length);
252             }
253             return getBeanProperty(values[position], property);
254         }
255     }
256 }
257
Popular Tags