package org.stagemonitor.core.util;

import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.TimeUnit;

import com.codahale.metrics.json.MetricsModule;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JsonUtils {

	private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);

	private static final ObjectMapper MAPPER = new ObjectMapper();

	static {
		/*
		 * Avoiding java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ser.BeanPropertyWriter.isUnwrapping()
		 * This happens, if the version of jackson databind less that the Afterburner version.
		 *
		 * One reason can be maven, because it resolves a version conflict with the nearest-wins strategy it is possible that
		 * jackson-module-afterburner is in a higher version that jackson-databind and jackson-core
		 *
		 * Another reason could be that a application server bundled version of jackson databind is used
		 */
		if (!System.getProperty("java.version").startsWith("1.6.") && versionsMatch(MAPPER.version(), new AfterburnerModule().version())) {
			MAPPER.registerModule(new AfterburnerModule());
		}
		MAPPER.registerModule(new MetricsModule(TimeUnit.SECONDS, TimeUnit.MILLISECONDS, false));
		MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
	}

	private JsonUtils() {
	}

	public static boolean versionsMatch(Version v1, Version v2) {
		return v1.getMajorVersion() == v2.getMajorVersion() &&
				v1.getMinorVersion() == v2.getMinorVersion() &&
				v1.getPatchLevel() == v2.getPatchLevel();
	}

	public static String toJson(Object o) {
		if (o == null) {
			return null;
		}
		try {
			return MAPPER.writeValueAsString(o);
		} catch (JsonProcessingException e) {
			logger.error(e.getMessage(), e);
			return null;
		}
	}

	public static String toJson(Object o, String exclude) {
		final ObjectNode jsonNode = MAPPER.valueToTree(o);
		jsonNode.remove(exclude);
		return jsonNode.toString();
	}

	public static void writeJsonToOutputStream(Object o, OutputStream os) throws IOException {
		MAPPER.writeValue(os, o);
	}

	public static ObjectMapper getMapper() {
		return MAPPER;
	}

	public static ObjectNode toObjectNode(Object o) {
		return MAPPER.valueToTree(o);
	}
}

@@ -758,704 +758,129 @@
 %7B%0A%09%09
-/*%0A%09%09 * Avoiding java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ser.BeanPropertyWriter.isUnwrapping()%0A%09%09 * This happens, if the version of jackson databind less that the Afterburner version.%0A%09%09 *%0A%09%09 * One reason can be maven, because it resolves a version conflict with the nearest-wins strategy it is possible that%0A%09%09 * jackson-module-afterburner is in a higher version that jackson-databind and jackson-core%0A%09%09 *%0A%09%09 * Another reason could be that a application server bundled version of jackson databind is used%0A%09%09 */%0A%09%09if (!System.getProperty(%22java.version%22).startsWith(%221.6.%22) && versionsMatch(MAPPER.version(), new AfterburnerModule().version())) %7B%0A%09%09%09MAPPER.registerModule(new 
+if (Double.parseDouble(System.getProperty(%22java.specification.version%22)) %3E 1.6) %7B%0A%09%09%09AfterburnerModuleRegisterer.register
 Afte
@@ -894,17 +894,16 @@
 Module()
-)
 ;%0A%09%09%7D%0A%09%09
@@ -1986,11 +1986,861 @@
 e(o);%0A%09%7D
+%0A%0A%09private static class AfterburnerModuleRegisterer %7B%0A%09%09private static void registerAfterburnerModule() %7B%0A%09%09%09/*%0A%09%09%09 * Avoiding java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ser.BeanPropertyWriter.isUnwrapping()%0A%09%09%09 * This happens, if the version of jackson databind less that the Afterburner version.%0A%09%09%09 *%0A%09%09%09 * One reason can be maven, because it resolves a version conflict with the nearest-wins strategy it is possible that%0A%09%09%09 * jackson-module-afterburner is in a higher version that jackson-databind and jackson-core%0A%09%09%09 *%0A%09%09%09 * Another reason could be that a application server bundled version of jackson databind is used%0A%09%09%09 */%0A%09%09%09final AfterburnerModule afterburnerModule = new AfterburnerModule();%0A%09%09%09if (versionsMatch(MAPPER.version(), afterburnerModule.version())) %7B%0A%09%09%09%09MAPPER.registerModule(afterburnerModule);%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D
 %0A%7D%0A

Make sure AfterburnerModule class is only loaded on jdk 1.7+