package com.limegroup.gnutella.bugs;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.httpclient.NameValuePair;
import com.limegroup.gnutella.RouterService;
import com.limegroup.gnutella.UDPService;
import com.limegroup.gnutella.gui.GUIMediator;
import com.limegroup.gnutella.settings.LimeProps;
import com.limegroup.gnutella.settings.Setting;
import com.limegroup.gnutella.settings.SettingsFactory;
import com.limegroup.gnutella.simpp.SimppManager;
import com.limegroup.gnutella.util.CommonUtils;
/**
* This class encapsulates all of the data for an individual client machine
* for an individual bug report.<p>
*
* This class collects all of the data for the local machine and provides
* access to that data in url-encoded form.
*/
//2345678|012345678|012345678|012345678|012345678|012345678|012345678|012345678|
public final class LocalClientInfo extends LocalAbstractInfo {
/**
* Creates information about this bug from the bug, thread, and detail.
*/
public LocalClientInfo(Throwable bug, String threadName, String detail, boolean fatal) {
//Store the basic information ...
_limewireVersion = CommonUtils.getLimeWireVersion();
_javaVersion = CommonUtils.getJavaVersion();
_javaVendor = prop("java.vendor");
_os = CommonUtils.getOS();
_osVersion = prop("os.version");
_architecture = prop("os.arch");
_freeMemory = "" + Runtime.getRuntime().freeMemory();
_totalMemory = "" + Runtime.getRuntime().totalMemory();
//Store information about the bug and the current thread.
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
bug.printStackTrace(pw);
pw.flush();
_bug = sw.toString();
_currentThread = threadName;
_bugName = bug.getClass().getName();
_fatalError = "" + fatal;
//Store the properties.
sw = new StringWriter();
pw = new PrintWriter(sw);
File propsFile = new File(CommonUtils.getUserSettingsDir(),
"limewire.props");
Properties props = new Properties();
// Load the properties from SettingsFactory, excluding
// FileSettings and FileArraySettings.
SettingsFactory sf = LimeProps.instance().getFactory();
synchronized(sf) {
Iterator it = sf.iterator();
while(it.hasNext()) {
Setting set = (Setting)it.next();
if(!set.isPrivate() && !set.isDefault())
props.put(set.getKey(), set.getValueAsString());
}
}
// list the properties in the PrintWriter.
props.list(pw);
pw.flush();
_props = sw.toString();
//Store extra debugging information.
if( GUIMediator.isConstructed() && RouterService.isStarted() ) {
_upTime = CommonUtils.seconds2time(
(int)(RouterService.getCurrentUptime()/1000));
_connected = "" + RouterService.isConnected();
_upToUp = ""+RouterService.getNumUltrapeerToUltrapeerConnections();
_upToLeaf = "" + RouterService.getNumUltrapeerToLeafConnections();
_leafToUp = "" + RouterService.getNumLeafToUltrapeerConnections();
_oldConnections = "" + RouterService.getNumOldConnections();
_ultrapeer = "" + RouterService.isSupernode();
_leaf = "" + RouterService.isShieldedLeaf();
_activeUploads = "" + RouterService.getNumUploads();
_queuedUploads = "" + RouterService.getNumQueuedUploads();
_activeDownloads = "" + RouterService.getNumActiveDownloads();
_httpDownloaders = "" +RouterService.getNumIndividualDownloaders();
_waitingDownloaders = "" + RouterService.getNumWaitingDownloads();
_acceptedIncoming = "" +RouterService.acceptedIncomingConnection();
_sharedFiles = "" + RouterService.getNumSharedFiles();
_guessCapable = "" + RouterService.isGUESSCapable();
_solicitedCapable= ""+RouterService.canReceiveSolicited();
_latestSIMPP= "" + SimppManager.instance().getVersion();
_portStable = "" +UDPService.instance().portStable();
_canDoFWT = "" + UDPService.instance().canDoFWT();
_lastReportedPort = ""+UDPService.instance().lastReportedPort();
_externalPort = ""+RouterService.getPort();
_receivedIpPong = ""+UDPService.instance().receivedIpPong();
}
//Store the detail, thread counts, and other information.
_detail = detail;
Thread[] allThreads = new Thread[Thread.activeCount()];
int copied = Thread.enumerate(allThreads);
_threadCount = "" + copied;
Map threads = new HashMap();
for(int i = 0; i < copied; i++) {
String name = allThreads[i].getName();
Object val = threads.get(name);
if(val == null)
threads.put(name, new Integer(1));
else {
int num = ((Integer)val).intValue()+1;
threads.put(name,new Integer(num));
}
}
sw = new StringWriter();
pw = new PrintWriter(sw);
for(Iterator i = threads.entrySet().iterator(); i.hasNext();) {
Map.Entry info = (Map.Entry)i.next();
pw.println( info.getKey() + ": " + info.getValue());
}
pw.flush();
_otherThreads = sw.toString();
}
/**
* Returns the System property with the given name, or
* "?" if it is unknown.
*/
private final String prop(String name) {
String value = System.getProperty(name);
if (value == null) return "?";
else return value;
}
/**
* Returns a an array of the name/value pairs of this info.
*
* @return an array of the name/value pairs of this info.
*/
public final NameValuePair[] getPostRequestParams() {
List params = new LinkedList();
append(params, LIMEWIRE_VERSION, _limewireVersion);
append(params, JAVA_VERSION, _javaVersion);
append(params, OS, _os);
append(params, OS_VERSION, _osVersion);
append(params, ARCHITECTURE, _architecture);
append(params, FREE_MEMORY, _freeMemory);
append(params, TOTAL_MEMORY, _totalMemory);
append(params, BUG, _bug);
append(params, CURRENT_THREAD, _currentThread);
append(params, PROPS, _props);
append(params, UPTIME, _upTime);
append(params, CONNECTED, _connected);
append(params, UP_TO_UP, _upToUp);
append(params, UP_TO_LEAF, _upToLeaf);
append(params, LEAF_TO_UP, _leafToUp);
append(params, OLD_CONNECTIONS, _oldConnections);
append(params, ULTRAPEER, _ultrapeer);
append(params, LEAF, _leaf);
append(params, ACTIVE_UPLOADS, _activeUploads);
append(params, QUEUED_UPLOADS, _queuedUploads);
append(params, ACTIVE_DOWNLOADS, _activeDownloads);
append(params, HTTP_DOWNLOADERS, _httpDownloaders);
append(params, WAITING_DOWNLOADERS, _waitingDownloaders);
append(params, ACCEPTED_INCOMING, _acceptedIncoming);
append(params, SHARED_FILES, _sharedFiles);
append(params, OTHER_THREADS, _otherThreads);
append(params, DETAIL, _detail);
append(params, OTHER_BUG, _otherBug);
append(params, JAVA_VENDOR, _javaVendor);
append(params, THREAD_COUNT, _threadCount);
append(params, BUG_NAME, _bugName);
append(params, GUESS_CAPABLE, _guessCapable);
append(params, SOLICITED_CAPABLE,_solicitedCapable);
append(params, LATEST_SIMPP,_latestSIMPP);
//append(params, IP_STABLE,_ipStable);
append(params, PORT_STABLE, _portStable);
append(params, CAN_DO_FWT, _canDoFWT);
append(params, LAST_REPORTED_PORT, _lastReportedPort);
append(params, EXTERNAL_PORT, _externalPort);
append(params, RECEIVED_IP_PONG, _receivedIpPong);
append(params, FATAL_ERROR, _fatalError);
return (NameValuePair[])params.toArray(
new NameValuePair[params.size()]);
}
/**
* Appends a NameValuePair of k/v to l if v is non-null.
*/
private final void append(List l, final String k, final String v){
if( v != null )
l.add(new NameValuePair(k, v));
}
}