1:
31:
32: package ;
33:
34: import ;
35: import ;
36: import ;
37:
38: import ;
39: import ;
40: import ;
41: import ;
42: import ;
43:
44:
49: public class CachingReportDataFactory implements ReportDataFactory
50: {
51: private static class Parameters implements DataSet
52: {
53: private Object[] dataStore;
54: private String[] nameStore;
55: private Integer hashCode;
56:
57: protected Parameters(final DataSet dataSet) throws DataSourceException
58: {
59: final int columnCount = dataSet.getColumnCount();
60: dataStore = new Object[columnCount];
61: nameStore = new String[columnCount];
62:
63: for (int i = 0; i < columnCount; i++)
64: {
65: nameStore[i] = dataSet.getColumnName(i);
66: dataStore[i] = dataSet.get(i);
67: }
68: }
69:
70: public int getColumnCount() throws DataSourceException
71: {
72: return dataStore.length;
73: }
74:
75: public String getColumnName(final int column) throws DataSourceException
76: {
77: return nameStore[column];
78: }
79:
80: public Object get(final int column) throws DataSourceException
81: {
82: return dataStore[column];
83: }
84:
85: public boolean equals(final Object o)
86: {
87: if (this == o)
88: {
89: return true;
90: }
91: if (o == null || getClass() != o.getClass())
92: {
93: return false;
94: }
95:
96: final Parameters that = (Parameters) o;
97:
98: if (!Arrays.equals(dataStore, that.dataStore))
99: {
100: return false;
101: }
102: if (!Arrays.equals(nameStore, that.nameStore))
103: {
104: return false;
105: }
106:
107: return true;
108: }
109:
110: public synchronized int hashCode()
111: {
112: if (hashCode != null)
113: {
114: return hashCode.intValue();
115: }
116: int hashCode = 0;
117: for (int i = 0; i < dataStore.length; i++)
118: {
119: final Object o = dataStore[i];
120: if (o != null)
121: {
122: hashCode = hashCode * 23 + o.hashCode();
123: }
124: else
125: {
126: hashCode = hashCode * 23;
127: }
128: }
129: for (int i = 0; i < nameStore.length; i++)
130: {
131: final Object o = nameStore[i];
132: if (o != null)
133: {
134: hashCode = hashCode * 23 + o.hashCode();
135: }
136: else
137: {
138: hashCode = hashCode * 23;
139: }
140: }
141: this.hashCode = new Integer(hashCode);
142: return hashCode;
143: }
144: }
145:
146: private HashMap queryCache;
147:
148: private ReportDataFactory backend;
149:
150: public CachingReportDataFactory(final ReportDataFactory backend)
151: {
152: if (backend == null)
153: {
154: throw new NullPointerException();
155: }
156: this.backend = backend;
157: this.queryCache = new HashMap();
158: }
159:
160: public void open()
161: {
162: backend.open();
163: }
164:
165:
175: public ReportData queryData(final String query, final DataSet parameters)
176: throws ReportDataFactoryException
177: {
178: try
179: {
180: final HashMap parameterCache = (HashMap) queryCache.get(query);
181: if (parameterCache == null)
182: {
183:
184: final HashMap newParams = new HashMap();
185: queryCache.put(query, newParams);
186:
187: final Parameters params = new Parameters(parameters);
188: final ReportData newData = backend.queryData(query, params);
189: newParams.put(params, newData);
190: newData.setCursorPosition(ReportData.BEFORE_FIRST_ROW);
191: return newData;
192: }
193: else
194: {
195:
196: final Parameters params = new Parameters(parameters);
197: final ReportData data = (ReportData) parameterCache.get(params);
198: if (data != null)
199: {
200: data.setCursorPosition(ReportData.BEFORE_FIRST_ROW);
201: return data;
202: }
203:
204: final ReportData newData = backend.queryData(query, params);
205: parameterCache.put(params, newData);
206: newData.setCursorPosition(ReportData.BEFORE_FIRST_ROW);
207: return newData;
208: }
209: }
210: catch (DataSourceException e)
211: {
212: e.printStackTrace();
213: throw new ReportDataFactoryException("Failed to query data", e);
214: }
215: }
216:
217:
220: public void close()
221: {
222: final Iterator queries = queryCache.values().iterator();
223: while (queries.hasNext())
224: {
225: final HashMap map = (HashMap) queries.next();
226: final Iterator dataSets = map.values().iterator();
227: while (dataSets.hasNext())
228: {
229: final ReportData data = (ReportData) dataSets.next();
230: try
231: {
232: data.close();
233: }
234: catch (DataSourceException e)
235: {
236:
237: }
238: }
239: }
240: backend.close();
241: }
242:
243:
249: public ReportDataFactory derive()
250: {
251:
252:
253:
254: throw new UnsupportedOperationException
255: ("The CachingReportDataFactory cannot be derived.");
256: }
257: }