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="edu.ucsb.nceas.metacat.util.SystemUtil"%><%@page 
17
import="java.util.Hashtable"%><%@ page 
18
language="java" %><%
19
/**
20
 * 
21
 * '$RCSfile$'
22
 * Copyright: 2008 Regents of the University of California and the
23
 *             National Center for Ecological Analysis and Synthesis
24
 *    '$Author: leinfelder $'
25
 *      '$Date: 2008-08-22 16:48:56 -0700 (Fri, 22 Aug 2008) $'
26
 * '$Revision: 4305 $'
27
 * 
28
 * This program is free software; you can redistribute it and/or modify
29
 * it under the terms of the GNU General Public License as published by
30
 * the Free Software Foundation; either version 2 of the License, or
31
 * (at your option) any later version.
32
 * 
33
 * This program is distributed in the hope that it will be useful,
34
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
35
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36
 * GNU General Public License for more details.
37
     
38
 * You should have received a copy of the GNU General Public License
39
 * along with this program; if not, write to the Free Software
40
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
41
 */  
42
%><%
43
Hashtable params = getParams(request);
44
handleDataquery(params,response,request.getSession().getId());
45
%><%!
46
	private Hashtable getParams(HttpServletRequest request) {
47
		Hashtable params = new Hashtable();
48
		Enumeration<String> paramlist = (Enumeration<String>)request.getParameterNames();
49
		while (paramlist.hasMoreElements()) {
50
	
51
			String name = paramlist.nextElement();
52
			String[] value = request.getParameterValues(name);
53
			params.put(name, value);
54
		}
55
	
56
		return params;
57
	}
58
%><%!
59
	private List processResultsSet(ResultSet rs, int omitColumn, String omitColumnLabel) throws SQLException {
60
		List retTable = new ArrayList();
61
		int colCount = rs.getMetaData().getColumnCount();
62
		List columnHeaders = new ArrayList();
63
		int recordCount = 1;
64
		OrderedMap uniqueIds = new OrderedMap();
65
		
66
		while (rs.next()) {
67
			List row = new ArrayList();
68
			//get the values for this row
69
			for (int i = 1; i <= colCount; i++) {
70

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

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