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

aQute.lib.json.MapHandler Maven / Gradle / Ivy

Go to download

A main program (executable JAR) that will listen to port 29998. At first, it can only answer that it is an Envoy (a limited agent). The only function it supports is installing a -runpath. It will then create a framework + agent and transfer the connection to the just installed agent who will then install the bundles. This JAR is a main command for JPM called bndremote. In JPM, it will start up with debug enabled. This JAR does some highly complicated class loading wizardy to ensure that it does not enforce any constraints on the -runpath.

The newest version!
package aQute.lib.json;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Supplier;

public class MapHandler extends Handler {
	final Class		rawClass;
	final Type			keyType;
	final Type			valueType;
	final Supplier	factory;

	MapHandler(Class rawClass, Type keyType, Type valueType) {

		if (rawClass != Map.class) {
			ParameterizedType type = findAncestor(rawClass, Map.class);
			this.keyType = keyType == Object.class ? resolve(type.getActualTypeArguments()[0]) : keyType;
			this.valueType = valueType == Object.class ? resolve(type.getActualTypeArguments()[1]) : valueType;
		} else {
			this.keyType = keyType;
			this.valueType = valueType;
		}

		if (rawClass.isInterface()) {
			if (rawClass.isAssignableFrom(LinkedHashMap.class))
				rawClass = LinkedHashMap.class;
			else if (rawClass.isAssignableFrom(TreeMap.class))
				rawClass = TreeMap.class;
			else if (rawClass.isAssignableFrom(Hashtable.class))
				rawClass = Hashtable.class;
			else if (rawClass.isAssignableFrom(HashMap.class))
				rawClass = HashMap.class;
			else if (rawClass.isAssignableFrom(Dictionary.class))
				rawClass = Hashtable.class;
			else
				throw new IllegalArgumentException("Unknown map interface: " + rawClass);
		}
		this.rawClass = rawClass;
		this.factory = newInstanceFunction(rawClass);
	}

	private Type resolve(Type type) {
		if (type instanceof TypeVariable tv) {
			Type[] bounds = tv.getBounds();
			return resolve(bounds[bounds.length - 1]);
		}
		return type;
	}

	private ParameterizedType findAncestor(Class start, Class target) {
		if (start == null || start == Object.class)
			return null;

		for (Type t : start.getGenericInterfaces()) {
			if (t instanceof ParameterizedType ptype) {
				if (ptype.getRawType() == target)
					return ptype;
			}
		}
		for (Class impls : start.getInterfaces()) {
			ParameterizedType ancestor = findAncestor(impls, target);
			if (ancestor != null)
				return ancestor;
		}

		return findAncestor(start.getSuperclass(), target);
	}

	@Override
	public void encode(Encoder app, Object object, Map visited) throws IOException, Exception {
		Map map = (Map) object;

		app.append("{");
		app.indent();
		String del = "";
		for (Map.Entry e : map.entrySet())
			try {
				app.append(del);
				if (!del.isEmpty()) {
					app.linebreak();
				}
				String key;
				if (e.getKey() != null && (keyType == String.class || keyType == Object.class))
					key = e.getKey()
						.toString();
				else {
					key = app.codec.enc()
						.put(e.getKey())
						.toString();
				}
				StringHandler.string(app, key);
				app.append(":");
				app.encode(e.getValue(), valueType, visited);
				del = ",";
			} catch (Exception ee) {
				throw new IllegalArgumentException("[\"" + e.getKey() + "\"]", ee);
			}
		app.undent();
		app.append("}");
	}

	@Override
	public Object decodeObject(Decoder r) throws Exception {
		assert r.current() == '{';

		@SuppressWarnings("unchecked")
		Map map = (Map) factory.get();

		int c = r.next();
		while (r.codec.isStartCharacter(c)) {
			Object key = r.codec.parseString(r);
			if (!(keyType == null || keyType == Object.class)) {
				Handler h = r.codec.getHandler(keyType, null);
				key = h.decode(r, (String) key);
			}

			c = r.skipWs();
			if (c != ':')
				throw new IllegalArgumentException("Expected ':' but got " + (char) c);

			c = r.next();
			Object value = r.codec.decode(valueType, r);
			if (value != null || !r.codec.ignorenull)
				map.put(key, value);

			c = r.skipWs();

			if (c == '}')
				break;

			if (c == ',') {
				c = r.next();
				continue;
			}

			if (r.codec.promiscuous && r.isEof()) {
				r.codec.fishy.incrementAndGet();
				return map;
			}

			throw new IllegalArgumentException(
				"Invalid character in parsing map, expected } or , but found " + (char) c);
		}
		if (c != '}') {
			r.fatal("Expected } but got " + (char) c);
		}
		r.read(); // skip closing
		return map;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy