Project

General

Profile

1 4872 leinfelder
<%@page
2
import="java.util.Iterator"%><%@page
3
import="java.util.ArrayList"%><%@page
4
import="edu.ucsb.nceas.utilities.OrderedMap"%><%@page
5
import="java.util.List"%><%@page
6
import="java.util.Enumeration"%><%@page
7
import="java.sql.SQLException"%><%@page
8
import="org.ecoinformatics.datamanager.transpose.DataTranspose"%><%@page
9
import="au.com.bytecode.opencsv.CSVWriter"%><%@page
10
import="java.io.OutputStreamWriter"%><%@page
11
import="java.io.Writer"%><%@page
12
import="java.sql.ResultSet"%><%@page
13
import="edu.ucsb.nceas.metacat.dataquery.DataQuery"%><%@page
14
import="java.io.IOException"%><%@page
15
import="edu.ucsb.nceas.utilities.PropertyNotFoundException"%><%@page
16
import="java.util.Hashtable"%><%@ page
17
language="java" %><%
18
/**
19
 *
20
 * '$RCSfile$'
21
 * Copyright: 2008 Regents of the University of California and the
22
 *             National Center for Ecological Analysis and Synthesis
23
 *    '$Author: leinfelder $'
24
 *      '$Date: 2008-08-22 16:48:56 -0700 (Fri, 22 Aug 2008) $'
25
 * '$Revision: 4305 $'
26
 *
27
 * This program is free software; you can redistribute it and/or modify
28
 * it under the terms of the GNU General Public License as published by
29
 * the Free Software Foundation; either version 2 of the License, or
30
 * (at your option) any later version.
31
 *
32
 * This program is distributed in the hope that it will be useful,
33
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
35
 * GNU General Public License for more details.
36
37
 * You should have received a copy of the GNU General Public License
38
 * along with this program; if not, write to the Free Software
39
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
40
 */
41
%><%
42
Hashtable params = getParams(request);
43
handleDataquery(params,response,request.getSession().getId());
44
%><%!
45
	private Hashtable getParams(HttpServletRequest request) {
46
		Hashtable params = new Hashtable();
47
		Enumeration<String> paramlist = (Enumeration<String>)request.getParameterNames();
48
		while (paramlist.hasMoreElements()) {
49
50
			String name = paramlist.nextElement();
51
			String[] value = request.getParameterValues(name);
52
			params.put(name, value);
53
		}
54
55
		return params;
56
	}
57
%><%!
58 4874 leinfelder
	private List transpose(ResultSet rs, int idCol, int pivotCol, List pivotAttributes, boolean omitIdValues) throws SQLException {
59 4875 leinfelder
		//map keyed by id column - data
60 4872 leinfelder
		OrderedMap table = new OrderedMap();
61 4875 leinfelder
		//track all the data columns
62 4872 leinfelder
		OrderedMap widestRow = new OrderedMap();
63 4875 leinfelder
		//map keyed by the pivot column - metadata
64
		OrderedMap headerRows = new OrderedMap();
65
66 4883 leinfelder
		//vocab columns
67
		String vocabNameCol = "qmetadatavocabulary";
68
		String vocabValueCol = "qmetadatavalue";
69
		//maps for the vocab lists
70
		OrderedMap vocabNames = new OrderedMap();
71
		OrderedMap vocabValues = new OrderedMap();
72
		//all vocab names/values
73
		List allVocabNames = new ArrayList();
74
		List allVocabValues = new ArrayList();
75 4892 leinfelder
		boolean twoColumnMetadata = true;
76 4883 leinfelder
77 4872 leinfelder
		int colCount = rs.getMetaData().getColumnCount();
78
		String idColName = rs.getMetaData().getColumnName(idCol);
79
80
		while (rs.next()) {
81
			String id = rs.getString(idCol);
82
			String pivotValue = rs.getString(pivotCol);
83
84 4875 leinfelder
			//look up the data row we are working on
85 4872 leinfelder
			OrderedMap row = (OrderedMap) table.get(id);
86
			if (row == null) {
87
				row = new OrderedMap();
88
			}
89 4875 leinfelder
			//look up the metadata row we are working on
90
			OrderedMap metadataRow = (OrderedMap) table.get(pivotValue);
91
			if (metadataRow == null) {
92
				metadataRow = new OrderedMap();
93
			}
94 4872 leinfelder
95
			//get the values for this pivot
96
			for (int i = 1; i <= colCount; i++) {
97
				if (i != pivotCol) {
98
					String colName = rs.getMetaData().getColumnName(i);
99 4875 leinfelder
					String value = rs.getString(i);
100 4876 leinfelder
					//clean up the value
101 4878 leinfelder
					if (value != null) {
102
						value = value.replaceAll("\n", " ");
103 4881 leinfelder
						value = value.replaceAll("\\s+", " ");
104 4878 leinfelder
						value = value.replaceAll("<html>", " ");
105
						value = value.replaceAll("</html>", " ");
106
						value = value.replaceAll("<head>", " ");
107
						value = value.replaceAll("</head>", " ");
108
						value = value.replaceAll("<body>", " ");
109
						value = value.replaceAll("</body>", " ");
110
					}
111 4874 leinfelder
					//do we include this column in the pivot?
112
					if (pivotAttributes.contains(colName)) {
113
						//annotate the column name with the pivot column value if not the id column
114
						if (i != idCol) {
115
							colName = pivotValue + "_" + colName;
116
						}
117
						row.put(colName, value);
118 4872 leinfelder
					}
119 4875 leinfelder
					else {
120 4885 leinfelder
						if (colName.startsWith(vocabNameCol) || colName.startsWith(vocabValueCol)) {
121
							//don't add it to the normal metadata
122
						}
123
						else {
124
							metadataRow.put(colName, value);
125
						}
126 4875 leinfelder
					}
127 4883 leinfelder
					//names
128
					if (colName.startsWith(vocabNameCol)) {
129
						List list = (List) vocabNames.get(pivotValue);
130
						if (list == null) {
131
							list = new ArrayList();
132
						}
133
						list.add(value);
134
						vocabNames.put(pivotValue, list);
135
						allVocabNames.add(value);
136
					}
137
					//values
138
					if (colName.startsWith(vocabValueCol)) {
139
						List list = (List) vocabValues.get(pivotValue);
140
						if (list == null) {
141
							list = new ArrayList();
142
						}
143
						list.add(value);
144
						vocabValues.put(pivotValue, list);
145
						allVocabValues.add(value);
146
					}
147 4872 leinfelder
				}
148
			}
149 4875 leinfelder
			//track the data columns - the values are junk
150 4872 leinfelder
			widestRow.putAll(row);
151
152
			//put the row back (or maybe it's the first time)
153 4875 leinfelder
			table.put(id, row);
154
155
			//put the metadata header back
156
			headerRows.put(pivotValue, metadataRow);
157
158 4872 leinfelder
		}
159
160 4883 leinfelder
		/** Construct the table structure for returning **/
161
162 4872 leinfelder
		//now make it into a list
163
		List retTable = new ArrayList();
164
165 4875 leinfelder
		//map keyed by metadata labels
166
		OrderedMap metadataHeaders = new OrderedMap();
167
168
		//do the data header - drives the other columns - based on widest entry
169 4872 leinfelder
		List header = new ArrayList(widestRow.keySet());
170 4875 leinfelder
171
		//do the metadata header rows (basically rotate them around)
172
		Iterator headerIter = header.iterator();
173 4886 leinfelder
		String lastValue = "";
174 4875 leinfelder
		while (headerIter.hasNext()) {
175
			String column = (String) headerIter.next();
176
			//get the pivotValue part of column name
177
			String pivotValue = column;
178
			try {
179
				pivotValue = column.substring(0, column.indexOf("_"));
180
			}
181
			catch (Exception e) {}
182
			//look up the row from the metadata - keyed by pivot value
183
			OrderedMap metadataRow = (OrderedMap) headerRows.get(pivotValue);
184
			if (metadataRow != null) {
185
				//go through the values
186
				Iterator metadataIter = metadataRow.keySet().iterator();
187
				while (metadataIter.hasNext()) {
188
					String key = (String) metadataIter.next();
189
					String value = (String) metadataRow.get(key);
190
					OrderedMap newMetadataRow = (OrderedMap) metadataHeaders.get(key);
191
					if (newMetadataRow == null) {
192
						newMetadataRow = new OrderedMap();
193
					}
194 4886 leinfelder
					//if it's the same as the last one, just use null value
195
					if (lastValue.equals(pivotValue)) {
196
						value = null;
197
					}
198 4875 leinfelder
					newMetadataRow.put(column, value);
199
					metadataHeaders.put(key, newMetadataRow);
200
				}
201
			}
202 4886 leinfelder
203
			lastValue = pivotValue;
204
205 4875 leinfelder
		}
206
207
		//make metadata rows as list/arrays on the reteurn table
208
		Iterator metadataLabelIter = metadataHeaders.keySet().iterator();
209
		while (metadataLabelIter.hasNext()) {
210
			String label = (String) metadataLabelIter.next();
211
			OrderedMap row = (OrderedMap) metadataHeaders.get(label);
212
			List rowValues = new ArrayList(row.values());
213
			rowValues.add(0, label);
214 4892 leinfelder
			if (twoColumnMetadata) {
215
				//add extra column
216
				rowValues.add(1, null);
217
			}
218 4875 leinfelder
			retTable.add(rowValues.toArray(new String[0]));
219
		}
220
221 4883 leinfelder
		//create the special vocab matrix rows
222
		List vocabTable = new ArrayList();
223
		List uniqueVocabs = new ArrayList();
224
		for (int i = 0; i < allVocabNames.size(); i++) {
225
			List vocabRow = new ArrayList();
226
			String vocabName = (String) allVocabNames.get(i);
227
			String vocabValue = (String) allVocabValues.get(i);
228
			String key = vocabName + "/" + vocabValue;
229
			//check if we've processed this already, skip if so
230
			if (uniqueVocabs.contains(key)) {
231
				continue;
232
			}
233 4892 leinfelder
			uniqueVocabs.add(key);
234
			if (twoColumnMetadata) {
235
				vocabRow.add(vocabName);
236
				vocabRow.add(vocabValue);
237
			}
238
			else {
239
				vocabRow.add(key);
240
			}
241 4883 leinfelder
			//go through the questions now, again
242
			headerIter = header.iterator();
243
			while (headerIter.hasNext()) {
244
				String column = (String) headerIter.next();
245
				//get the pivotValue part of column name if it exists
246
				String pivotValue = null;
247
				try {
248
					pivotValue = column.substring(0, column.indexOf("_"));
249
				}
250
				catch (Exception e) {}
251
				if (pivotValue == null) {
252
					continue;
253
				}
254
				//check to see if this question has that keyword
255
				List names = (List) vocabNames.get(pivotValue);
256
				List values = (List) vocabValues.get(pivotValue);
257
				if (names != null && names.indexOf(vocabName) > -1 && names.indexOf(vocabName) == values.indexOf(vocabValue) ) {
258
					vocabRow.add("true");
259
				}
260
				else {
261
					vocabRow.add("false");
262
				}
263
			}
264
			//put the row on
265
			vocabTable.add(vocabRow.toArray(new String[0]));
266
		}
267
268
		//put the vocab matrix on the table
269
		retTable.addAll(vocabTable);
270
271 4892 leinfelder
		if (twoColumnMetadata) {
272
			//add column to data header row
273
			header.add(1, null);
274
		}
275 4875 leinfelder
		//put the data header row on the table
276 4872 leinfelder
		retTable.add(header.toArray(new String[0]));
277
278 4875 leinfelder
		//now the value rows in the table
279 4872 leinfelder
		Iterator rowIter = table.values().iterator();
280
		int rowCount = 1;
281
		while (rowIter.hasNext()) {
282
			OrderedMap rowMap = (OrderedMap) rowIter.next();
283
			List row = new ArrayList();
284
			//iterate over the widest row's columns
285
			Iterator columnIter = widestRow.keySet().iterator();
286
			while (columnIter.hasNext()) {
287
				Object key = columnIter.next();
288
				Object value = rowMap.get(key);
289
				//hide the value used for Ids - just increment row
290
				if (key.equals(idColName) && omitIdValues) {
291
					value = String.valueOf(rowCount);
292
				}
293
				row.add(value);
294
			}
295
			rowCount++;
296 4892 leinfelder
			if (twoColumnMetadata) {
297
				//add extra column
298
				row.add(1, null);
299
			}
300 4872 leinfelder
			retTable.add(row.toArray(new String[0]));
301
		}
302
303
		return retTable;
304
	}
305
%><%!
306
	private void handleDataquery(
307
			Hashtable<String, String[]> params,
308
	        HttpServletResponse response,
309
	        String sessionId) throws PropertyNotFoundException, IOException {
310
311
		DataQuery dq = null;
312
		if (sessionId != null) {
313
			dq = new DataQuery(sessionId);
314
		}
315
		else {
316
			dq = new DataQuery();
317
		}
318
319
		String dataqueryXML = (params.get("dataquery"))[0];
320
321
		ResultSet rs = null;
322
		try {
323
			rs = dq.executeQuery(dataqueryXML);
324
		} catch (Exception e) {
325
			//probably need to do something here
326
			e.printStackTrace();
327
			return;
328
		}
329
330
		//process the result set
331
		String qformat = "csv";
332
		String[] temp = params.get("qformat");
333
		if (temp != null && temp.length > 0) {
334
			qformat = temp[0];
335
		}
336
		String fileName = "query-results." + qformat;
337
338
		boolean transpose = false;
339
		temp = params.get("transpose");
340
		if (temp != null && temp.length > 0) {
341
			transpose = Boolean.parseBoolean(temp[0]);
342
		}
343
		int observation = 0;
344
		temp = params.get("observation");
345
		if (temp != null && temp.length > 0) {
346
			observation = Integer.parseInt(temp[0]);
347
		}
348
		int pivot = 0;
349
		temp = params.get("pivot");
350
		if (temp != null && temp.length > 0) {
351
			pivot = Integer.parseInt(temp[0]);
352
		}
353
354
		//get the results as csv file
355
		if (qformat != null && qformat.equalsIgnoreCase("csv")) {
356
			response.setContentType("text/csv");
357
			//response.setContentType("application/csv");
358
	        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
359
360
			Writer writer = new OutputStreamWriter(response.getOutputStream());
361 4876 leinfelder
			//CSVWriter csv = new CSVWriter(writer, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER);
362
			CSVWriter csv = new CSVWriter(writer, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.DEFAULT_QUOTE_CHARACTER, CSVWriter.DEFAULT_ESCAPE_CHARACTER);
363 4872 leinfelder
			try {
364
				if (transpose) {
365 4874 leinfelder
					List pivotCols = new ArrayList();
366
					pivotCols.add("studentid");
367
					pivotCols.add("score");
368
					pivotCols.add("response");
369
					List transposedTable = transpose(rs, observation, pivot, pivotCols, true);
370 4872 leinfelder
					csv.writeAll(transposedTable);
371
				} else {
372
					csv.writeAll(rs, true);
373
				}
374
375
				csv.flush();
376
				response.flushBuffer();
377
378
				rs.close();
379
380
			} catch (SQLException e) {
381
				e.printStackTrace();
382
			}
383
384
			return;
385
		}
386
387
	}
388
%>