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

spinjar.com.minidev.json.reader.JsonWriter Maven / Gradle / Ivy

package net.minidev.json.reader;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import net.minidev.json.JSONAware;
import net.minidev.json.JSONAwareEx;
import net.minidev.json.JSONStreamAware;
import net.minidev.json.JSONStreamAwareEx;
import net.minidev.json.JSONStyle;
import net.minidev.json.JSONValue;

public class JsonWriter {
	private ConcurrentHashMap, JsonWriterI> data;
	private LinkedList writerInterfaces;

	public JsonWriter() {
		data = new ConcurrentHashMap, JsonWriterI>();
		writerInterfaces = new LinkedList();
		init();
	}

	/**
	 * remap field name in custom classes
	 * 
	 * @param fromJava
	 *            field name in java
	 * @param toJson
	 *            field name in json
	 * @since 2.1.1
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public  void remapField(Class type, String fromJava, String toJson) {
		JsonWriterI map = this.getWrite(type);
		if (!(map instanceof BeansWriterASMRemap)) {
			map = new BeansWriterASMRemap();
			registerWriter(map, type);
		}
		((BeansWriterASMRemap) map).renameField(fromJava, toJson);
	}

	static class WriterByInterface {
		public Class _interface;
		public JsonWriterI _writer;

		public WriterByInterface(Class _interface, JsonWriterI _writer) {
			this._interface = _interface;
			this._writer = _writer;
		}
	}
	
	/**
	 * try to find a Writer by Checking implemented interface
	 * @param clazz class to serialize
	 * @return a Writer or null
	 */
	@SuppressWarnings("rawtypes")
	public JsonWriterI getWriterByInterface(Class clazz) {
		for (WriterByInterface w : writerInterfaces) {
			if (w._interface.isAssignableFrom(clazz))
				return w._writer;
		}
		return null;
	}

	@SuppressWarnings("rawtypes")
	public JsonWriterI getWrite(Class cls) {
		return data.get(cls);
	}

	final static public JsonWriterI JSONStreamAwareWriter = new JsonWriterI() {
		public  void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException {
			value.writeJSONString(out);
		}
	};

	final static public JsonWriterI JSONStreamAwareExWriter = new JsonWriterI() {
		public  void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException {
			value.writeJSONString(out, compression);
		}
	};

	final static public JsonWriterI JSONJSONAwareExWriter = new JsonWriterI() {
		public  void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException {
			out.append(value.toJSONString(compression));
		}
	};

	final static public JsonWriterI JSONJSONAwareWriter = new JsonWriterI() {
		public  void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException {
			out.append(value.toJSONString());
		}
	};

	final static public JsonWriterI> JSONIterableWriter = new JsonWriterI>() {
		public > void writeJSONString(E list, Appendable out, JSONStyle compression) throws IOException {
			boolean first = true;
			compression.arrayStart(out);
			for (Object value : list) {
				if (first) {
					first = false;
					compression.arrayfirstObject(out);
				} else {
					compression.arrayNextElm(out);
				}
				if (value == null)
					out.append("null");
				else
					JSONValue.writeJSONString(value, out, compression);
				compression.arrayObjectEnd(out);
			}
			compression.arrayStop(out);
		}
	};

	final static public JsonWriterI> EnumWriter = new JsonWriterI>() {
		public > void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException {
			@SuppressWarnings("rawtypes")
			String s = ((Enum) value).name();
			compression.writeString(out, s);
		}
	};

	final static public JsonWriterI> JSONMapWriter = new JsonWriterI>() {
		public > void writeJSONString(E map, Appendable out, JSONStyle compression) throws IOException {
			boolean first = true;
			compression.objectStart(out);
			/**
			 * do not use  to handle non String key maps
			 */
			for (Map.Entry entry : map.entrySet()) {
				Object v = entry.getValue();
				if (v == null && compression.ignoreNull())
					continue;
				if (first) {
					compression.objectFirstStart(out);
					first = false;
				} else {
					compression.objectNext(out);
				}
				JsonWriter.writeJSONKV(entry.getKey().toString(), v, out, compression);
				// compression.objectElmStop(out);
			}
			compression.objectStop(out);
		}
	};

	/**
	 * Json-Smart V2 Beans serialiser
	 * 
	 * Based on ASM
	 */
	final static public JsonWriterI beansWriterASM = new BeansWriterASM();

	/**
	 * Json-Smart V1 Beans serialiser
	 */
	final static public JsonWriterI beansWriter = new BeansWriter();
	
	/**
	 * Json-Smart ArrayWriterClass
	 */
	final static public JsonWriterI arrayWriter = new ArrayWriter();
	
	/**
	 * ToString Writer
	 */
	final static public JsonWriterI toStringWriter = new JsonWriterI() {
		public void writeJSONString(Object value, Appendable out, JSONStyle compression) throws IOException {
			out.append(value.toString());
		}
	};
	
	public void init() {
		registerWriter(new JsonWriterI() {
			public void writeJSONString(String value, Appendable out, JSONStyle compression) throws IOException {
				compression.writeString(out, (String) value);
			}
		}, String.class);

		registerWriter(new JsonWriterI() {
			public void writeJSONString(Double value, Appendable out, JSONStyle compression) throws IOException {
				if (value.isInfinite())
					out.append("null");
				else
					out.append(value.toString());
			}
		}, Double.class);

		registerWriter(new JsonWriterI() {
			public void writeJSONString(Date value, Appendable out, JSONStyle compression) throws IOException {
				out.append('"');
				JSONValue.escape(value.toString(), out, compression);
				out.append('"');
			}
		}, Date.class);

		registerWriter(new JsonWriterI() {
			public void writeJSONString(Float value, Appendable out, JSONStyle compression) throws IOException {
				if (value.isInfinite())
					out.append("null");
				else
					out.append(value.toString());
			}
		}, Float.class);

		registerWriter(toStringWriter, Integer.class, Long.class, Byte.class, Short.class, BigInteger.class, BigDecimal.class);
		registerWriter(toStringWriter, Boolean.class);

		/**
		 * Array
		 */

		registerWriter(new JsonWriterI() {
			public void writeJSONString(int[] value, Appendable out, JSONStyle compression) throws IOException {
				boolean needSep = false;
				compression.arrayStart(out);
				for (int b : value) {
					if (needSep)
						compression.objectNext(out);
					else
						needSep = true;
					out.append(Integer.toString(b));
				}
				compression.arrayStop(out);
			}
		}, int[].class);

		registerWriter(new JsonWriterI() {
			public void writeJSONString(short[] value, Appendable out, JSONStyle compression) throws IOException {
				boolean needSep = false;
				compression.arrayStart(out);
				for (short b : value) {
					if (needSep)
						compression.objectNext(out);
					else
						needSep = true;
					out.append(Short.toString(b));
				}
				compression.arrayStop(out);
			}
		}, short[].class);

		registerWriter(new JsonWriterI() {
			public void writeJSONString(long[] value, Appendable out, JSONStyle compression) throws IOException {
				boolean needSep = false;
				compression.arrayStart(out);
				for (long b : value) {
					if (needSep)
						compression.objectNext(out);
					else
						needSep = true;
					out.append(Long.toString(b));
				}
				compression.arrayStop(out);
			}
		}, long[].class);

		registerWriter(new JsonWriterI() {
			public void writeJSONString(float[] value, Appendable out, JSONStyle compression) throws IOException {
				boolean needSep = false;
				compression.arrayStart(out);
				for (float b : value) {
					if (needSep)
						compression.objectNext(out);
					else
						needSep = true;
					out.append(Float.toString(b));
				}
				compression.arrayStop(out);
			}
		}, float[].class);

		registerWriter(new JsonWriterI() {
			public void writeJSONString(double[] value, Appendable out, JSONStyle compression) throws IOException {
				boolean needSep = false;
				compression.arrayStart(out);
				for (double b : value) {
					if (needSep)
						compression.objectNext(out);
					else
						needSep = true;
					out.append(Double.toString(b));
				}
				compression.arrayStop(out);
			}
		}, double[].class);

		registerWriter(new JsonWriterI() {
			public void writeJSONString(boolean[] value, Appendable out, JSONStyle compression) throws IOException {
				boolean needSep = false;
				compression.arrayStart(out);
				for (boolean b : value) {
					if (needSep)
						compression.objectNext(out);
					else
						needSep = true;
					out.append(Boolean.toString(b));
				}
				compression.arrayStop(out);
			}
		}, boolean[].class);

		registerWriterInterface(JSONStreamAwareEx.class, JsonWriter.JSONStreamAwareExWriter);
		registerWriterInterface(JSONStreamAware.class, JsonWriter.JSONStreamAwareWriter);
		registerWriterInterface(JSONAwareEx.class, JsonWriter.JSONJSONAwareExWriter);
		registerWriterInterface(JSONAware.class, JsonWriter.JSONJSONAwareWriter);
		registerWriterInterface(Map.class, JsonWriter.JSONMapWriter);
		registerWriterInterface(Iterable.class, JsonWriter.JSONIterableWriter);
		registerWriterInterface(Enum.class, JsonWriter.EnumWriter);
		registerWriterInterface(Number.class, JsonWriter.toStringWriter);
	}

	/**
	 * associate an Writer to a interface With Hi priority
	 * @param interFace interface to map
	 * @param writer writer Object
	 * @deprecated use registerWriterInterfaceFirst
	 */
	public void addInterfaceWriterFirst(Class interFace, JsonWriterI writer) {
		registerWriterInterfaceFirst(interFace, writer);
	}

	/**
	 * associate an Writer to a interface With Low priority
	 * @param interFace interface to map
	 * @param writer writer Object
	 * @deprecated use registerWriterInterfaceLast
	 */
	public void addInterfaceWriterLast(Class interFace, JsonWriterI writer) {
		registerWriterInterfaceLast(interFace, writer);
	}

	/**
	 * associate an Writer to a interface With Low priority
	 * @param interFace interface to map
	 * @param writer writer Object
	 */
	public void registerWriterInterfaceLast(Class interFace, JsonWriterI writer) {
		writerInterfaces.addLast(new WriterByInterface(interFace, writer));
	}
	
	/**
	 * associate an Writer to a interface With Hi priority
	 * @param interFace interface to map
	 * @param writer writer Object
	 */
	public void registerWriterInterfaceFirst(Class interFace, JsonWriterI writer) {
		writerInterfaces.addFirst(new WriterByInterface(interFace, writer));
	}

	/**
	 * an alias for registerWriterInterfaceLast
	 * @param interFace interface to map
	 * @param writer writer Object
	 */
	public void registerWriterInterface(Class interFace, JsonWriterI writer) {
		registerWriterInterfaceLast(interFace, writer);
	}

	/**
	 * associate an Writer to a Class
	 * @param writer
	 * @param cls
	 */
	public  void registerWriter(JsonWriterI writer, Class... cls) {
		for (Class c : cls)
			data.put(c, writer);
	}

	/**
	 * Write a Key : value entry to a stream
	 */
	public static void writeJSONKV(String key, Object value, Appendable out, JSONStyle compression) throws IOException {
		if (key == null)
			out.append("null");
		else if (!compression.mustProtectKey(key))
			out.append(key);
		else {
			out.append('"');
			JSONValue.escape(key, out, compression);
			out.append('"');
		}
		compression.objectEndOfKey(out);
		if (value instanceof String) {
			compression.writeString(out, (String) value);
		} else
			JSONValue.writeJSONString(value, out, compression);
		compression.objectElmStop(out);
	}
}