package com.googlecode.jmxtrans.jobs;

import com.googlecode.jmxtrans.connections.JMXConnectionParams;
import com.googlecode.jmxtrans.jmx.JmxUtils;
import com.googlecode.jmxtrans.model.Server;
import com.sun.tools.attach.VirtualMachine;
import org.apache.commons.pool.impl.GenericKeyedObjectPool;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXServiceURL;
import java.io.File;

/**
 * This is a quartz job that is responsible for executing a Server object on a
 * cron schedule that is defined within the Server object.
 *
 * @author jon
 */
public class ServerJob implements Job {

	private static final String CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress";

	private static final Logger log = LoggerFactory.getLogger(ServerJob.class);

	private final GenericKeyedObjectPool<JMXConnectionParams, JMXConnector> jmxPool;

	private final JmxUtils jmxUtils;

	@Inject
	public ServerJob(GenericKeyedObjectPool<JMXConnectionParams, JMXConnector> jmxPool, JmxUtils jmxUtils) {
		this.jmxPool = jmxPool;
		this.jmxUtils = jmxUtils;
	}

	public void execute(JobExecutionContext context) throws JobExecutionException {
		JobDataMap map = context.getMergedJobDataMap();
		Server server = (Server) map.get(Server.class.getName());

		log.debug("+++++ Started server job: {}", server);

		JMXConnector conn = null;
		JMXConnectionParams connectionParams = null;

		try {
			JMXServiceURL jmxUrl;
			if(server.getPid() != null) {
				jmxUrl = extractJMXServiceURLFromPid(server.getPid());
			}
			else {
				jmxUrl = new JMXServiceURL(server.getUrl());
			}

			connectionParams = new JMXConnectionParams(jmxUrl, server.getEnvironment());
			if (!server.isLocal()) {
				conn = jmxPool.borrowObject(connectionParams);
			}
			jmxUtils.processServer(server, conn);
		} catch (Exception e) {
			log.error("Error in job for server: " + server, e);
			throw new JobExecutionException(e);
		} finally {
			try {
				jmxPool.returnObject(connectionParams, conn);
			} catch (Exception ex) {
				log.error("Error returning object to pool for server: " + server);
			}
		}

		log.debug("+++++ Finished server job: {}", server);
	}

	private JMXServiceURL extractJMXServiceURLFromPid(String pid) throws Exception
	{
		// attach to the target application
		VirtualMachine vm = VirtualMachine.attach(pid	);

		try {
			// get the connector address
			String connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);

			// no connector address, so we start the JMX agent
			if (connectorAddress == null) {
				String agent = vm.getSystemProperties().getProperty("java.home") +
					File.separator + "lib" + File.separator + "management-agent.jar";
				vm.loadAgent(agent);

				// agent is started, get the connector address
				connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
			}

			// establish connection to connector server
			return new JMXServiceURL(connectorAddress);
		}
		finally
		{
			vm.detach();
		}
	}
}

@@ -2469,46 +2469,8 @@
 %0A%09%7B%0A
-%09%09// attach to the target application%0A
 %09%09Vi
@@ -2512,17 +2512,16 @@
 tach(pid
-%09
 );%0A%0A%09%09tr
@@ -2528,40 +2528,8 @@
 y %7B%0A
-%09%09%09// get the connector address%0A
 %09%09%09S
@@ -2614,62 +2614,8 @@
 );%0A%0A
-%09%09%09// no connector address, so we start the JMX agent%0A
 %09%09%09i
@@ -2817,59 +2817,8 @@
 );%0A%0A
-%09%09%09%09// agent is started, get the connector address%0A
 %09%09%09%09
@@ -2902,55 +2902,8 @@
 %09%7D%0A%0A
-%09%09%09// establish connection to connector server%0A
 %09%09%09r
@@ -2958,19 +2958,17 @@
 %09finally
-%0A%09%09
+ 
 %7B%0A%09%09%09vm.

Remove redundant comments