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

org.eclipse.core.internal.resources.MarkerAttributeMap Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2000, 2022 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     James Blackburn (Broadcom Corp.) - ongoing development
 *     Lars Vogel  - Bug 473427
 *     Joerg Kubitz - redesign
 *******************************************************************************/
package org.eclipse.core.internal.resources;

import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.core.internal.utils.IStringPoolParticipant;
import org.eclipse.core.internal.utils.StringPool;

/**
 * A specialized Map implementation that is optimized for a small
 * set of strings as keys. The keys will be interned() on insert.
 *
 * Unlike a java.util.HashMap nulls are neither allowed for key or value.
 */
// the Map interface is not implemented as it would allow to insert null key or values
// or non interned keys via the iterator if not a specific entrySet is implemented.
public class MarkerAttributeMap implements IStringPoolParticipant {
	// This implementation is a copy on write map.
	private final AtomicReference> mapRef;

	// Typically contains 9 keys:
	// "severity","sourceId","charStart","charEnd","arguments","id","message","lineNumber","categoryId"
	protected static final int DEFAULT_SIZE = 9;

	/**
	 * Creates a new marker attribute map of default size
	 */
	public MarkerAttributeMap() {
		this(DEFAULT_SIZE);
	}

	/**
	 * Creates a new marker attribute map.
	 *
	 * @param initialCapacity The initial number of elements that will fit in the
	 *                        map.
	 */
	public MarkerAttributeMap(int initialCapacity) {
		// ignore initialCapacity - a copy on write datastructure will be copied anyway.
		mapRef = new AtomicReference<>(Map.of());
	}

	/**
	 * Copy constructor. Note that a java.util.Map can not be passed since it could
	 * contain null keys or null values, or keys that are not interned.
	 */
	public MarkerAttributeMap(MarkerAttributeMap m) {
		mapRef = new AtomicReference<>(copy(m.getMap()));
	}

	/**
	 * Copy constructor. Entries with null keys are not allowed. Entries with null
	 * values are silently ignored.
	 */
	public MarkerAttributeMap(Map map, boolean validate) {
		mapRef = new AtomicReference<>(copy(map, validate));
	}

	/**
	 * delete all previous values and replace with given map. Entries with null keys
	 * are not allowed. Entries with null values are silently ignored.
	 */
	public void setAttributes(Map map, boolean validate) {
		mapRef.set(copy(map, validate));
	}

	private Map copy(Map map, boolean validate) {
		Map target = new HashMap<>();
		putAll(target, map, validate);
		return target;
	}

	/**
	 * puts all entries of the given map. Entries with null keys are not allowed.
	 * Entries with null values are silently ignored.
	 */
	public void putAll(Map map, boolean validate) {
		mapRef.getAndUpdate(old -> {
			Map copy = copy(old);
			putAll(copy, map, validate);
			return copy;
		});
	}

	private void putAll(Map target, Map source, boolean validate) {
		if (source == null) {
			return;
		}
		for (Entry e : source.entrySet()) {
			String key = e.getKey();
			Objects.requireNonNull(key, "insert of null key not allowed"); //$NON-NLS-1$
			Object value = e.getValue();
			if (validate) {
				value = MarkerInfo.checkValidAttribute(value);
			}
			if (value != null) { // null values => ignore
				target.put(e.getKey().intern(), value);
			}
		}
	}

	private Map copy(Map map) {
		return new HashMap<>(map);
	}

	private Map getMap() {
		return mapRef.get();
	}

	/** creates a copy that fulfills the java.util.Map interface **/
	public Map toMap() {
		return copy(this.getMap());
	}

	/** @see java.util.Map#entrySet **/
	public Set> entrySet() {
		return getMap().entrySet();
	}

	/**
	 * like {@link java.util.Map#put(Object, Object)} but null keys or values are
	 * not allowed
	 */
	public void put(String k, Object value) {
		Objects.requireNonNull(k, "insert of null key not allowed"); //$NON-NLS-1$
		Objects.requireNonNull(value, "insert of null value not allowed"); //$NON-NLS-1$
		mapRef.getAndUpdate(map -> {
			Map m = copy(map);
			m.put(k.intern(), value);
			return m;
		});
	}

	@Override
	public void shareStrings(StringPool set) {
		// don't share keys because they are already interned
		for (java.util.Map.Entry e : getMap().entrySet()) {
			Object o = e.getValue();
			if (o instanceof String) {
				e.setValue(set.add((String) o));
			} else if (o instanceof IStringPoolParticipant) {
				((IStringPoolParticipant) o).shareStrings(set);
			}
		}
	}

	/** @see java.util.Map#isEmpty **/
	public boolean isEmpty() {
		return getMap().isEmpty();
	}

	/** @see java.util.Map#remove **/
	public Object remove(Object key) {
		return getMap().remove(key);
	}

	/** @see java.util.Map#get **/
	public Object get(Object key) {
		return getMap().get(key);
	}

	/** @see java.util.Map#size **/
	public int size() {
		return getMap().size();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy