001: /*
002: * Copyright 2004-2007 Gary Bentley
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may
005: * not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015: package org.josql.contrib;
016:
017: import java.util.List;
018:
019: import net.sf.jasperreports.engine.JRRewindableDataSource;
020: import net.sf.jasperreports.engine.JRField;
021:
022: import org.josql.QueryExecutionException;
023: import org.josql.Query;
024: import org.josql.QueryResults;
025:
026: /**
027: * A data source suitable for use with <a href="http://jasperreports.sourceforge.net/">JasperReports</a>.
028: * This is basically just an extension to {@link Query} that allows the
029: * results to be iterated over, thereby providing the ability for objects to be reported on
030: * that are held in memory.
031: * <p>
032: * One limitation here is that the SQL query must return columns rather than the objects
033: * since the values need to be mapped by JasperReports. For example:
034: * <pre>
035: * SELECT lastModified,
036: * name
037: * FROM java.io.File
038: * WHERE name LIKE '%.html'
039: * </pre>
040: * <p>
041: * This query would work but it should be noted that the select "columns" (since they do not have
042: * aliases assigned) will be labeled 1, 2, X and so on.
043: * You can assign aliases to the "columns" and then use them in the report definition file.
044: * <p>
045: * Please note: due to my bewilderment (and the fact that I can't get the examples to work ;)
046: * I haven't been able to adequately test this implementation, in the rudementary tests I
047: * performed it seemed to work. If it doesn't please send me an example so that I can try
048: * it!
049: */
050: public class JoSQLJRDataSource extends Query implements
051: JRRewindableDataSource {
052:
053: private int row = 0;
054: private List results = null;
055:
056: public JoSQLJRDataSource() {
057:
058: }
059:
060: /**
061: * Exectute the query and return the results. A reference to the results is also held to
062: * allow them to be iterated over. If you plan on re-using this data source then
063: * you should call: {@link #clearResults()} to free up the references to the results.
064: *
065: * @param l The List of objects to execute the query on.
066: * @return The results.
067: * @throws QueryExecutionException If the query cannot be executed, or if the query
068: * is set to return objects rather than "columns".
069: */
070: public QueryResults executeQuery(List l)
071: throws QueryExecutionException {
072:
073: if (this .isWantObjects()) {
074:
075: throw new QueryExecutionException(
076: "Only SQL statements that return columns (not the objects passed in) can be used.");
077:
078: }
079:
080: QueryResults qr = super .execute(l);
081:
082: this .results = qr.getResults();
083:
084: return qr;
085:
086: }
087:
088: public List getResults() {
089:
090: return this .results;
091:
092: }
093:
094: public void clearResults() {
095:
096: this .results = null;
097:
098: }
099:
100: public Object getFieldValue(JRField field) {
101:
102: // Get the row of objects.
103: List res = (List) this .results.get(this .row);
104:
105: Integer ind = (Integer) this .getAliases().get(field.getName());
106:
107: int i = -1;
108:
109: if (ind != null) {
110:
111: i = ind.intValue();
112:
113: if (i > (res.size() - 1)) {
114:
115: return null;
116:
117: }
118:
119: }
120:
121: // Get the index for the field name.
122: return res.get(i);
123:
124: }
125:
126: public boolean next() {
127:
128: if (this .row < (this .results.size() - 1)) {
129:
130: this .row++;
131:
132: return true;
133:
134: }
135:
136: return false;
137:
138: }
139:
140: public void moveFirst() {
141:
142: this .row = 0;
143:
144: }
145:
146: }
|