All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.almende.util.jackson.JOM Maven / Gradle / Ivy

The newest version!
/**
 * Singleton Jackson ObjectMapper
 */
package com.almende.util.jackson;

import java.io.IOException;
import java.util.BitSet;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.datatype.joda.JodaModule;

/**
 * The Class JOM.
 */
public final class JOM {
	private static final ObjectMapper	MAPPER;
	static {
		MAPPER = createInstance();
	}

	/**
	 * Instantiates a new jom.
	 */
	protected JOM() {}

	/**
	 * Gets the single instance of JOM.
	 * 
	 * @return single instance of JOM
	 */
	public static ObjectMapper getInstance() {
		return MAPPER;
	}

	/**
	 * Creates the object node.
	 * 
	 * @return the object node
	 */
	public static ObjectNode createObjectNode() {
		return MAPPER.createObjectNode();
	}

	/**
	 * Creates the array node.
	 * 
	 * @return the array node
	 */
	public static ArrayNode createArrayNode() {
		return MAPPER.createArrayNode();
	}

	/**
	 * Creates the null node.
	 * 
	 * @return the null node
	 */
	public static NullNode createNullNode() {
		return NullNode.getInstance();
	}

	/**
	 * Creates the instance.
	 * 
	 * @return the object mapper
	 */
	private static synchronized ObjectMapper createInstance() {
		final ObjectMapper mapper = new ObjectMapper();

		// set configuration
		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
				false);
		mapper.configure(
				DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, false);
		mapper.getFactory().configure(
				JsonFactory.Feature.CANONICALIZE_FIELD_NAMES, false);

		// Needed for o.a. JsonFileState
		mapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
		mapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);

		mapper.registerModule(new JodaModule());

		SimpleModule throwableModule = new SimpleModule("ThrowableModule",
				new Version(1, 0, 0, null, null, null)) {
			private static final long	serialVersionUID	= -7028757133086455336L;

			@Override
			public void setupModule(SetupContext context) {
				context.setMixInAnnotations(Throwable.class,
						ThrowableMixin.class);
			}
		};
		mapper.registerModule(throwableModule);

		SimpleModule bitSetModule = new SimpleModule("BitSetModule",
				new Version(1, 0, 0, null, null, null));
		bitSetModule.addSerializer(new JOM().new CustomBitSetSerializer());
		bitSetModule.addDeserializer(BitSet.class,
				new JOM().new CustomBitSetDeserializer());
		mapper.registerModule(bitSetModule);

		return mapper;
	}

	/**
	 * Gets the type factory.
	 * 
	 * @return the type factory
	 */
	public static TypeFactory getTypeFactory() {
		return MAPPER.getTypeFactory();
	}

	/**
	 * Gets the void.
	 * 
	 * @return the void
	 * @deprecated This method is no longer needed, you can directly use
	 *             Void.class
	 */
	@Deprecated
	public static JavaType getVoid() {
		return MAPPER.getTypeFactory().uncheckedSimpleType(Void.class);
	}

	/**
	 * Gets the simple type.
	 * 
	 * @param c
	 *            the c
	 * @return the simple type
	 * @deprecated This method is no longer needed, you can directly use
	 *             .class, e.g. String.class
	 */
	@Deprecated
	public static JavaType getSimpleType(final Class c) {
		return MAPPER.getTypeFactory().uncheckedSimpleType(c);
	}

	/**
	 * The Class CustomBitSetSerializer.
	 */
	public class CustomBitSetSerializer extends StdSerializer {

		/**
		 * Instantiates a new custom bit set serializer.
		 */
		public CustomBitSetSerializer() {
			super(BitSet.class, true);
		}

		@Override
		public void serialize(BitSet value, JsonGenerator jgen,
				SerializerProvider provider) throws IOException,
				JsonGenerationException {
			jgen.writeStartObject();
			jgen.writeNumberField("size", value.size());
			jgen.writeStringField("hex", bytesToHex(value.toByteArray()));
			jgen.writeEndObject();
		}

	}

	/**
	 * The Class CustomBitSetDeserializer.
	 */
	public class CustomBitSetDeserializer extends StdDeserializer {
		private static final long	serialVersionUID	= 8734051359812526123L;

		/**
		 * Instantiates a new custom bit set deserializer.
		 */
		public CustomBitSetDeserializer() {
			super(BitSet.class);
		}

		@Override
		public BitSet deserialize(JsonParser jpar, DeserializationContext ctx)
				throws IOException, JsonProcessingException {
			final JsonNode node = jpar.readValueAsTree();
			if (!node.isObject()) {
				throw ctx.mappingException(BitSet.class);
			}
			final ObjectNode obj = (ObjectNode) node;
			final int size = obj.get("size").asInt();
			final byte[] value = hexToBytes(obj.get("hex").asText());
			final BitSet result = BitSet.valueOf(value);
			result.set(result.length(), size, false);
			return result;
		}

	}

	// From: http://stackoverflow.com/a/9855338
	final private static char[]	hexArray	= "0123456789ABCDEF".toCharArray();

	private static String bytesToHex(byte[] bytes) {
		char[] hexChars = new char[bytes.length * 2];
		for (int j = 0; j < bytes.length; j++) {
			int v = bytes[j] & 0xFF;
			hexChars[j * 2] = hexArray[v >>> 4];
			hexChars[j * 2 + 1] = hexArray[v & 0x0F];
		}
		return new String(hexChars);
	}

	// From: http://stackoverflow.com/a/140861
	private static byte[] hexToBytes(String s) {
		int len = s.length();
		byte[] data = new byte[len / 2];
		for (int i = 0; i < len; i += 2) {
			data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character
					.digit(s.charAt(i + 1), 16));
		}
		return data;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy