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

com.networknt.jsonoverlay.MapOverlay Maven / Gradle / Ivy

Go to download

A fork of RepreZen JsonOverlay with all dependencies and code generation removed

There is a newer version: 2.1.36
Show newest version
/*********************************************************************
 *  Copyright (c) 2017 ModelSolv, Inc. and others.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 *  Contributors:
 *     ModelSolv, Inc.
 *     - initial API and implementation and/or initial documentation
 **********************************************************************/
package com.networknt.jsonoverlay;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Pattern;

import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.networknt.jsonoverlay.SerializationOptions.Option;

public final class MapOverlay extends JsonOverlay> {

	private final OverlayFactory valueFactory;
	private final Pattern keyPattern;
	private Map> overlays = new LinkedHashMap<>();
	private boolean elaborated = false;

	private MapOverlay(JsonNode json, JsonOverlay parent, OverlayFactory> factory,
			ReferenceManager refMgr) {
		super(json, parent, factory, refMgr);
		MapOverlayFactory mapOverlayFactory = (MapOverlayFactory) factory;
		this.valueFactory = mapOverlayFactory.getValueFactory();
		String keyPattern = mapOverlayFactory.getKeyPattern();
		this.keyPattern = keyPattern != null ? Pattern.compile(keyPattern) : null;
	}

	private MapOverlay(Map value, JsonOverlay parent, OverlayFactory> factory,
			ReferenceManager refMgr) {
		super(new LinkedHashMap<>(value), parent, factory, refMgr);
		MapOverlayFactory mapOverlayFactory = (MapOverlayFactory) factory;
		this.valueFactory = mapOverlayFactory.getValueFactory();
		String keyPattern = mapOverlayFactory.getKeyPattern();
		this.keyPattern = keyPattern != null ? Pattern.compile(keyPattern) : null;
	}

	@Override
	protected JsonOverlay _findInternal(JsonPointer path) {
		String key = path.getMatchingProperty();
		return overlays.containsKey(key) ? overlays.get(key)._find(path.tail()) : null;
	}

	@Override
	protected Map _fromJson(JsonNode json) {
		return new LinkedHashMap() {
			private static final long serialVersionUID = 1L;

			@SuppressWarnings("unused")
			public MapOverlay getOverlay() {
				return MapOverlay.this;
			}
		};
	}

	@Override
	protected JsonNode _toJsonInternal(SerializationOptions options) {
		ObjectNode obj = _jsonObject();
		for (Entry> entry : overlays.entrySet()) {
			obj.set(entry.getKey(), entry.getValue()._toJson(options.minus(Option.KEEP_ONE_EMPTY)));
		}
		return obj.size() > 0 || options.isKeepThisEmpty() ? obj : _jsonMissing();
	}

	@Override
	protected boolean _isElaborated() {
		return elaborated;
	}

	@Override
	protected void _elaborate(boolean atCreation) {
		if (json != null) {
			fillWithJson();
		} else {
			fillWithValues();
		}
		elaborated = true;
	}

	private void fillWithJson() {
		value.clear();
		overlays.clear();
		for (Iterator> iter = json.fields(); iter.hasNext();) {
			Entry entry = iter.next();
			if (keyPattern == null || keyPattern.matcher(entry.getKey()).matches()) {
				JsonOverlay valOverlay = valueFactory.create(entry.getValue(), this, refMgr);
				overlays.put(entry.getKey(), valOverlay);
				valOverlay._setPathInParent(entry.getKey());
				value.put(entry.getKey(), valOverlay._get(false));
			}
		}
	}

	private void fillWithValues() {
		overlays.clear();
		for (Entry entry : value.entrySet()) {
			JsonOverlay valOverlay = valueOverlayFor(entry.getValue());
			overlays.put(entry.getKey(), valOverlay);
			valOverlay._setPathInParent(entry.getKey());
		}
	}

	private JsonOverlay valueOverlayFor(V val) {
		return valueFactory.create(val, this, refMgr);
	}

	public V get(String key) {
		JsonOverlay valOverlay = overlays.get(key);
		return valOverlay != null ? valOverlay._get() : null;
	}

	/* package */ JsonOverlay _getOverlay(String key) {
		return overlays.get(key);
	}

	public Set keySet() {
		return value.keySet();
	}

	public void set(String key, V val) {
		value.put(key, val);
		overlays.put(key, valueOverlayFor(val));
	}

	public void remove(String key) {
		value.remove(key);
		overlays.remove(key);
	}

	public int size() {
		return overlays.size();
	}

	@Override
	public boolean equals(Object obj) {
		return equals(obj, false);
	}

	public boolean equals(Object obj, boolean sameOrder) {
		if (obj instanceof MapOverlay) {
			MapOverlay castObj = (MapOverlay) obj;
			return overlays.equals(castObj.overlays) && (!sameOrder || checkOrder(castObj));
		}
		return false;
	}

	private boolean checkOrder(MapOverlay other) {
		Iterator myKeys = overlays.keySet().iterator();
		Iterator theirKeys = other.overlays.keySet().iterator();
		while (myKeys.hasNext() && theirKeys.hasNext()) {
			if (!myKeys.next().equals(theirKeys.next())) {
				return false;
			}
		}
		return !myKeys.hasNext() && !theirKeys.hasNext();
	}

	@Override
	public int hashCode() {
		return overlays.hashCode();
	}

	public static  OverlayFactory> getFactory(OverlayFactory valueFactory, String keyPattern) {
		return new MapOverlayFactory(valueFactory, keyPattern);
	}

	@Override
	protected OverlayFactory> _getFactory() {
		return factory;
	}

	private static class MapOverlayFactory extends OverlayFactory> {
		private final OverlayFactory valueFactory;
		private final String keyPattern;

		public MapOverlayFactory(OverlayFactory valueFactory, String keyPattern) {
			this.valueFactory = valueFactory;
			this.keyPattern = keyPattern;
		}

		@Override
		public String getSignature() {
			return String.format("map[%s|%s]", valueFactory.getSignature(), keyPattern != null ? keyPattern : "*");
		}

		@Override
		protected Class>> getOverlayClass() {
			Class overlayClass = MapOverlay.class;
			@SuppressWarnings("unchecked")
			Class>> castClass = (Class>>) overlayClass;
			return castClass;
		}

		@Override
		protected JsonOverlay> _create(Map value, JsonOverlay parent,
				ReferenceManager refMgr) {
			return new MapOverlay(value, parent, this, refMgr);
		}

		@Override
		protected JsonOverlay> _create(JsonNode json, JsonOverlay parent, ReferenceManager refMgr) {
			return new MapOverlay(json, parent, this, refMgr);
		}

		public String getKeyPattern() {
			return keyPattern;
		}

		public OverlayFactory getValueFactory() {
			return valueFactory;
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy