Project

General

Profile

1
<%@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
	private List processResultsSet(ResultSet rs, int omitColumn) throws SQLException {
59
		List retTable = new ArrayList();
60
		int colCount = rs.getMetaData().getColumnCount();
61
		List columnHeaders = new ArrayList();
62
		int recordCount = 1;
63
		OrderedMap uniqueIds = new OrderedMap();
64
		
65
		while (rs.next()) {
66
			List row = new ArrayList();
67
			//get the values for this row
68
			for (int i = 1; i <= colCount; i++) {
69
				if (recordCount == 1) {
70
					String colName = rs.getMetaData().getColumnName(i);
71
					columnHeaders.add(colName);
72
				}
73
				
74
				String value = rs.getString(i);
75
					
76
				//clean up the value
77
				value = cleanUp(value);
78
				
79
				//hide the ids
80
				if (i == omitColumn) {
81
					String lookupValue = (String) uniqueIds.get(value);
82
					if (lookupValue == null) {
83
						lookupValue = recordCount + "";
84
					}
85
					uniqueIds.put(value, lookupValue);
86
					value = lookupValue;
87
				}
88
				
89
				row.add(value);
90
			}
91
			retTable.add(row.toArray(new String[0]));
92
			recordCount++;
93
		}
94
		retTable.add(0, columnHeaders.toArray(new String[0]));
95
		return retTable;
96
	}
97
%><%!
98
	private List transpose(ResultSet rs, int idCol, int pivotCol, List pivotAttributes, boolean omitIdValues) throws SQLException {
99
		//map keyed by id column - data
100
		OrderedMap table = new OrderedMap();
101
		//track all the data columns
102
		OrderedMap widestRow = new OrderedMap();
103
		//map keyed by the pivot column - metadata
104
		OrderedMap headerRows = new OrderedMap();
105
		
106
		//vocab columns
107
		String vocabNameCol = "qmetadatavocabulary";
108
		String vocabValueCol = "qmetadatavalue";
109
		//maps for the vocab lists
110
		OrderedMap vocabNames = new OrderedMap();
111
		OrderedMap vocabValues = new OrderedMap();
112
		//all vocab names/values
113
		List allVocabNames = new ArrayList();
114
		List allVocabValues = new ArrayList();
115
		boolean twoColumnMetadata = true;
116
		
117
		int colCount = rs.getMetaData().getColumnCount();
118
		String idColName = rs.getMetaData().getColumnName(idCol);
119
		
120
		while (rs.next()) {
121
			String id = rs.getString(idCol);
122
			String pivotValue = rs.getString(pivotCol);
123
			
124
			//look up the data row we are working on
125
			OrderedMap row = (OrderedMap) table.get(id);
126
			if (row == null) {
127
				row = new OrderedMap();
128
			}
129
			//look up the metadata row we are working on
130
			OrderedMap metadataRow = (OrderedMap) table.get(pivotValue);
131
			if (metadataRow == null) {
132
				metadataRow = new OrderedMap();
133
			}
134
			
135
			//get the values for this pivot
136
			for (int i = 1; i <= colCount; i++) {
137
				if (i != pivotCol) {
138
					String colName = rs.getMetaData().getColumnName(i);
139
					String value = rs.getString(i);
140
					
141
					//clean up the value
142
					value = cleanUp(value);
143
					
144
					//do we include this column in the pivot?
145
					if (pivotAttributes.contains(colName)) {
146
						//annotate the column name with the pivot column value if not the id column
147
						if (i != idCol) {
148
							colName = pivotValue + "_" + colName;
149
						}
150
						row.put(colName, value);
151
					}
152
					else {
153
						if (colName.startsWith(vocabNameCol) || colName.startsWith(vocabValueCol)) {
154
							//don't add it to the normal metadata
155
						}
156
						else {
157
							metadataRow.put(colName, value);
158
						}
159
					}
160
					//names
161
					if (colName.startsWith(vocabNameCol)) {
162
						List list = (List) vocabNames.get(pivotValue);
163
						if (list == null) {
164
							list = new ArrayList();
165
						}
166
						list.add(value);
167
						vocabNames.put(pivotValue, list);
168
						allVocabNames.add(value);
169
					}
170
					//values
171
					if (colName.startsWith(vocabValueCol)) {
172
						List list = (List) vocabValues.get(pivotValue);
173
						if (list == null) {
174
							list = new ArrayList();
175
						}
176
						list.add(value);
177
						vocabValues.put(pivotValue, list);
178
						allVocabValues.add(value);
179
					}
180
				}
181
			}
182
			//track the data columns - the values are junk
183
			widestRow.putAll(row);
184
			
185
			//put the row back (or maybe it's the first time)
186
			table.put(id, row);
187
			
188
			//put the metadata header back
189
			headerRows.put(pivotValue, metadataRow);
190
			
191
		}
192
		
193
		/** Construct the table structure for returning **/
194
		
195
		//now make it into a list
196
		List retTable = new ArrayList();
197
		
198
		//map keyed by metadata labels
199
		OrderedMap metadataHeaders = new OrderedMap();
200
		
201
		//do the data header - drives the other columns - based on widest entry
202
		List header = new ArrayList(widestRow.keySet());
203
		
204
		//do the metadata header rows (basically rotate them around)
205
		Iterator headerIter = header.iterator();
206
		String lastValue = "";
207
		while (headerIter.hasNext()) {
208
			String column = (String) headerIter.next();
209
			//get the pivotValue part of column name
210
			String pivotValue = column;
211
			try {
212
				pivotValue = column.substring(0, column.indexOf("_"));
213
			}
214
			catch (Exception e) {}
215
			//look up the row from the metadata - keyed by pivot value
216
			OrderedMap metadataRow = (OrderedMap) headerRows.get(pivotValue);
217
			if (metadataRow != null) {
218
				//go through the values
219
				Iterator metadataIter = metadataRow.keySet().iterator();
220
				while (metadataIter.hasNext()) {
221
					String key = (String) metadataIter.next();
222
					String value = (String) metadataRow.get(key);
223
					OrderedMap newMetadataRow = (OrderedMap) metadataHeaders.get(key);
224
					if (newMetadataRow == null) {
225
						newMetadataRow = new OrderedMap();
226
					}
227
					//if it's the same as the last one, just use null value
228
					if (lastValue.equals(pivotValue)) {
229
						value = null;
230
					} 
231
					newMetadataRow.put(column, value);
232
					metadataHeaders.put(key, newMetadataRow);
233
				}
234
			}
235
			
236
			lastValue = pivotValue;
237

    
238
		}
239
		
240
		//make metadata rows as list/arrays on the reteurn table
241
		Iterator metadataLabelIter = metadataHeaders.keySet().iterator();
242
		while (metadataLabelIter.hasNext()) {
243
			String label = (String) metadataLabelIter.next();
244
			OrderedMap row = (OrderedMap) metadataHeaders.get(label);
245
			List rowValues = new ArrayList(row.values());
246
			rowValues.add(0, label);
247
			if (twoColumnMetadata) {
248
				//add extra column
249
				rowValues.add(1, null);
250
			}
251
			retTable.add(rowValues.toArray(new String[0]));
252
		}
253
		
254
		//create the special vocab matrix rows
255
		List vocabTable = new ArrayList();
256
		List uniqueVocabs = new ArrayList();
257
		for (int i = 0; i < allVocabNames.size(); i++) {
258
			List vocabRow = new ArrayList();
259
			String vocabName = (String) allVocabNames.get(i);
260
			String vocabValue = (String) allVocabValues.get(i);
261
			String key = vocabName + "/" + vocabValue;
262
			//check if we've processed this already, skip if so
263
			if (uniqueVocabs.contains(key)) {
264
				continue;
265
			}
266
			uniqueVocabs.add(key);			
267
			if (twoColumnMetadata) {
268
				vocabRow.add(vocabName);
269
				vocabRow.add(vocabValue);
270
			}
271
			else {
272
				vocabRow.add(key);
273
			}
274
			//go through the questions now, again
275
			headerIter = header.iterator();
276
			while (headerIter.hasNext()) {
277
				String column = (String) headerIter.next();
278
				//get the pivotValue part of column name if it exists
279
				String pivotValue = null;
280
				try {
281
					pivotValue = column.substring(0, column.indexOf("_"));
282
				}
283
				catch (Exception e) {}
284
				if (pivotValue == null) {
285
					continue;
286
				}
287
				//check to see if this question has that keyword
288
				List names = (List) vocabNames.get(pivotValue);
289
				List values = (List) vocabValues.get(pivotValue);
290
				if (names != null && names.indexOf(vocabName) > -1 && names.indexOf(vocabName) == values.indexOf(vocabValue) ) {
291
					vocabRow.add("true");
292
				}
293
				else {
294
					vocabRow.add("false");
295
				}
296
			}
297
			//put the row on
298
			vocabTable.add(vocabRow.toArray(new String[0]));
299
		}
300
		
301
		//put the vocab matrix on the table
302
		retTable.addAll(vocabTable);
303
		
304
		if (twoColumnMetadata) {
305
			//add column to data header row
306
			header.add(1, null);
307
		}
308
		//put the data header row on the table
309
		retTable.add(header.toArray(new String[0]));
310
		
311
		//now the value rows in the table
312
		Iterator rowIter = table.values().iterator();
313
		int rowCount = 1;
314
		while (rowIter.hasNext()) {
315
			OrderedMap rowMap = (OrderedMap) rowIter.next();
316
			List row = new ArrayList();
317
			//iterate over the widest row's columns
318
			Iterator columnIter = widestRow.keySet().iterator();
319
			while (columnIter.hasNext()) {
320
				Object key = columnIter.next();
321
				Object value = rowMap.get(key);
322
				//hide the value used for Ids - just increment row
323
				if (key.equals(idColName) && omitIdValues) {
324
					value = String.valueOf(rowCount);
325
				}
326
				row.add(value);
327
			}
328
			rowCount++;
329
			if (twoColumnMetadata) {
330
				//add extra column
331
				row.add(1, null);
332
			}
333
			retTable.add(row.toArray(new String[0]));
334
		}
335
		
336
		return retTable;
337
	}
338
%><%!
339
	private String cleanUp(String value) {
340
		if (value != null) {
341
			value = value.replaceAll("\n", " ");
342
			value = value.replaceAll("\\s+", " ");
343
			value = value.replaceAll("<html>", " ");
344
			value = value.replaceAll("</html>", " ");
345
			value = value.replaceAll("<head>", " ");
346
			value = value.replaceAll("</head>", " ");
347
			value = value.replaceAll("<body>", " ");
348
			value = value.replaceAll("</body>", " ");
349
		}
350
		return value;
351
	}
352
%><%!
353
	private void handleDataquery(
354
			Hashtable<String, String[]> params,
355
	        HttpServletResponse response,
356
	        String sessionId) throws PropertyNotFoundException, IOException {
357
		
358
		DataQuery dq = null;
359
		if (sessionId != null) {
360
			dq = new DataQuery(sessionId);
361
		}
362
		else {
363
			dq = new DataQuery();
364
		}
365
		
366
		String dataqueryXML = (params.get("dataquery"))[0];
367
	
368
		ResultSet rs = null;
369
		try {
370
			rs = dq.executeQuery(dataqueryXML);
371
		} catch (Exception e) {
372
			//probably need to do something here
373
			e.printStackTrace();
374
			return;
375
		}
376
		
377
		//process the result set
378
		String qformat = "csv";
379
		String[] temp = params.get("qformat");
380
		if (temp != null && temp.length > 0) {
381
			qformat = temp[0];
382
		}
383
		String fileName = "query-results." + qformat;
384
		
385
		boolean transpose = false;
386
		temp = params.get("transpose");
387
		if (temp != null && temp.length > 0) {
388
			transpose = Boolean.parseBoolean(temp[0]);
389
		}
390
		int observation = 0;
391
		temp = params.get("observation");
392
		if (temp != null && temp.length > 0) {
393
			observation = Integer.parseInt(temp[0]);
394
		}
395
		int pivot = 0;
396
		temp = params.get("pivot");
397
		if (temp != null && temp.length > 0) {
398
			pivot = Integer.parseInt(temp[0]);
399
		}
400
		
401
		//get the results as csv file
402
		if (qformat != null && qformat.equalsIgnoreCase("csv")) {
403
			response.setContentType("text/csv");
404
			//response.setContentType("application/csv");
405
	        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
406
	        
407
			Writer writer = new OutputStreamWriter(response.getOutputStream());
408
			//CSVWriter csv = new CSVWriter(writer, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER);
409
			CSVWriter csv = new CSVWriter(writer, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.DEFAULT_QUOTE_CHARACTER, CSVWriter.DEFAULT_ESCAPE_CHARACTER);
410
			try {
411
				if (transpose) {
412
					List pivotCols = new ArrayList();
413
					pivotCols.add("studentid");
414
					pivotCols.add("score");
415
					pivotCols.add("response");
416
					List transposedTable = transpose(rs, observation, pivot, pivotCols, true);
417
					csv.writeAll(transposedTable);
418
				} else {
419
					List processedTable = processResultsSet(rs, 3);
420
					csv.writeAll(processedTable);
421
				}
422
				
423
				csv.flush();
424
				response.flushBuffer();
425
				
426
				rs.close();
427
				
428
			} catch (SQLException e) {
429
				e.printStackTrace();
430
			}
431
			
432
			return;
433
		}
434
		
435
	}
436
%>
(4-4/22)