/******************************************************************************* * Copyright (c) 2008-2009 Cambridge Semantics Incorporated. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.openanzo.analysis; import java.io.PrintStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.apache.commons.collections15.set.ListOrderedSet; /** * * @author Lee Feigenbaum ( <a href="mailto:lee@cambridgesemantics.com">lee@cambridgesemantics.com </a>) * * Outputs requests and responses with these fields: * * Type : "request" or "response" JMS Correlation ID : the correlation ID of the request/response Request User : the user that made the request (empty * for responses) Run As User : the user that the request ran as (empty for responses) Destination : the destination service of the request (empty for * responses) Prop1 Prop2 ... PropN : value (if any) of the property, for all properties mentioned in the full set of requests & responses handled Body * : the body of the request or response * * Note: the current approach here stores everything in memory in order to be able to determine a complete set of properties before outputting anything * (CSV is a "square" format and we'd like to treat properties as columns). If this becomes a problem, there are two solutions: + adapt the * {@link RequestHandlerOutputProvider} pattern to allow a double pass through the data + output to a temporary file while accumulating properties, and * at the end() transform the temp file to the final form * */ public class CsvOutputRequestHandler implements RequestHandlerOutputProvider { private PrintStream out = null; private Set<String> properties = new ListOrderedSet<String>(); private static class Entry { private String type; private String jmsCorrelationId; private String requestUser; private String runAsUser; private String destination; private Map<String, String> props; private String body; private Entry(String type, String jmsCorrelationId, String requestUser, String runAsUser, String destination, Map<String, String> props, String body) { this.type = type; this.jmsCorrelationId = jmsCorrelationId; this.requestUser = requestUser; this.runAsUser = runAsUser; this.destination = destination; this.props = props; this.body = body; } } private ArrayList<Entry> entries = new ArrayList<Entry>(); public Object handleRequest(String body, Map<String, String> properties, String requestUser, String runAsUser, String destination, String jmsCorrelationId) throws Exception { //System.err.println("handling *request*/response: "+ ++cnt); for (String k : properties.keySet()) this.properties.add(k); this.entries.add(new Entry("request", jmsCorrelationId, requestUser, runAsUser, destination, properties, body)); return null; } public void handleResponse(String body, Map<String, String> properties, Map<String, String> analysisProperties, String jmsCorrelationId) { //System.err.println("handling request/*response*: "+ ++cnt); for (String k : properties.keySet()) this.properties.add(k); for (String k : analysisProperties.keySet()) this.properties.add(k); Map<String, String> props = new HashMap<String, String>(properties); props.putAll(analysisProperties); this.entries.add(new Entry("response", jmsCorrelationId, "", "", "", props, body)); } public void setOutputStream(PrintStream out) { this.out = out; } public void start() { } public void end() { this.out.print(prepareStringForCSVEntry("Type")); this.out.print(","); this.out.print(prepareStringForCSVEntry("JMS Correlation ID")); this.out.print(","); this.out.print(prepareStringForCSVEntry("Request User")); this.out.print(","); this.out.print(prepareStringForCSVEntry("Run As User")); this.out.print(","); this.out.print(prepareStringForCSVEntry("Destination")); for (String p : this.properties) { this.out.print(","); this.out.print(prepareStringForCSVEntry(p)); } this.out.print(","); this.out.print(prepareStringForCSVEntry("Body")); this.out.println(); for (Entry e : this.entries) { this.out.print(prepareStringForCSVEntry(e.type)); this.out.print(","); this.out.print(prepareStringForCSVEntry(e.jmsCorrelationId)); this.out.print(","); this.out.print(prepareStringForCSVEntry(e.requestUser)); this.out.print(","); this.out.print(prepareStringForCSVEntry(e.runAsUser)); this.out.print(","); this.out.print(prepareStringForCSVEntry(e.destination)); for (String p : this.properties) { this.out.print(","); this.out.print(prepareStringForCSVEntry(e.props.get(p))); } this.out.print(","); this.out.print(prepareStringForCSVEntry(e.body)); this.out.println(); } } static private String prepareStringForCSVEntry(String s) { if (s == null || s.length() == 0) return ""; // 1) replace any double quotes with doubled double quotes s = s.replace("\"", "\"\""); // 2) replace any tab characters with 4 space characters, since Excel doesn't handle tab characters in a cell s = s.replace("\t", " "); // 3) wrap in double quotes return "\"" + s + "\""; } }