/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights reserved. <a>http://www.crunii.com</a>
 */
package com.crunii.micro.common.xml.fast;

import java.util.Map;

import com.crunii.micro.common.jackson.DateModule;
import com.crunii.micro.common.jackson.URIModule;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;

/**
 * @author 田平 create 2020年4月30日上午10:56:14
 *
 */
public class FastXmlUtil {

	private static XmlMapper xmlMapper;
	static {
		xmlMapper = new XmlMapper();
		SimpleModule module = new SimpleModule().addDeserializer(Object.class, FixedUntypedObjectDeserializer.getInstance());
		xmlMapper.registerModule(module);
		xmlMapper.registerModule(new DateModule());
		xmlMapper.registerModule(new URIModule());
		Hibernate5Module hModule = new Hibernate5Module();
		hModule.enable(Hibernate5Module.Feature.FORCE_LAZY_LOADING);
		xmlMapper.registerModule(hModule);

		xmlMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
		xmlMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
		xmlMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
		xmlMapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
		xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
	}

	public static XmlMapper getXmlMapper() {
		return xmlMapper;
	}

	public static String objectToXml(String root, Object obj) {
		try {
			return xmlMapper.writer().withRootName(root).writeValueAsString(obj);
		} catch (JsonProcessingException e) {
			throw new RuntimeException("mapToXml error!", e);
		}
	}

	public static String objectToPrettyXml(String root, Object obj) {
		try {
			return xmlMapper.writerWithDefaultPrettyPrinter().withRootName(root).writeValueAsString(obj);
		} catch (JsonProcessingException e) {
			throw new RuntimeException("mapToXml error!", e);
		}
	}

	public static Map<String, Object> xmlToMap(String xml) {
		try {
			return xmlMapper.readValue(xml, new TypeReference<Map<String, Object>>() {});
		} catch (Exception e) {
			throw new RuntimeException("xmlToMap error!", e);
		}
	}

	public static <T> T xmlToObject(String xml, Class<T> genericType) {
		try {
			return xmlMapper.readValue(xml, genericType);
		} catch (Exception e) {
			throw new RuntimeException("xmlToObject error!", e);
		}
	}

	public static <T> T xmlToObject(String xml, TypeReference<T> valueTypeRef) {
		try {
			return xmlMapper.readValue(xml, valueTypeRef);
		} catch (Exception e) {
			throw new RuntimeException("xmlToObject error!", e);
		}
	}

}
