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

spoon.support.util.ModelSet Maven / Gradle / Ivy

Go to download

Spoon is a tool for meta-programming, analysis and transformation of Java programs.

There is a newer version: 11.1.1-beta-14
Show newest version
/*
 * SPDX-License-Identifier: (MIT OR CECILL-C)
 *
 * Copyright (C) 2006-2023 INRIA and contributors
 *
 * Spoon is available either under the terms of the MIT License (see LICENSE-MIT.txt) or the Cecill-C License (see LICENSE-CECILL-C.txt). You as the user are entitled to choose the terms under which to adopt Spoon.
 */
package spoon.support.util;

import static spoon.support.util.internal.ModelCollectionUtils.linkToParent;

import java.io.Serializable;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

import spoon.SpoonException;
import spoon.support.modelobs.FineModelChangeListener;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.path.CtRole;

/**
 * The implementation of the {@link Set}, which is used by Spoon model objects.
 * It assures:
 * 1) each inserted {@link CtElement} gets assigned correct parent
 * 2) each change is reported in {@link FineModelChangeListener}
 *
 * @deprecated This set is no longer actively used or maintained. It is only kept for backwards
 * compatibility and might be removed in a future release.
 */
@Deprecated
public abstract class ModelSet extends AbstractSet implements Serializable {
	private static final long serialVersionUID = 1L;

	private final Set set;

	protected ModelSet(Comparator comparator) {
		set = Collections.synchronizedSet(new TreeSet<>(comparator));
	}

	protected abstract CtElement getOwner();
	protected abstract CtRole getRole();
	protected void onSizeChanged(int newSize) {
	}

	@Override
	public int size() {
		return set.size();
	}

	@Override
	public boolean isEmpty() {
		return set.isEmpty();
	}

	@Override
	public boolean contains(Object o) {
		return set.contains(o);
	}

	@Override
	public Object[] toArray() {
		return set.toArray();
	}

	@Override
	public  T[] toArray(T[] a) {
		return set.toArray(a);
	}

	@Override
	public boolean add(T e) {
		if (e == null) {
			return false;
		}
		CtElement owner = getOwner();
		linkToParent(owner, e);
		getModelChangeListener().onSetAdd(owner, getRole(), set, e);

		// we make sure that the element is always the last put in the set
		// for being least suprising for client code
		set.remove(e);
		set.add(e);
		return true;
	}

	@Override
	public boolean remove(Object o) {
		if (!set.contains(o)) {
			return false;
		}
		@SuppressWarnings("unchecked")
		T e = (T) o;
		getModelChangeListener().onSetDelete(getOwner(), getRole(), set, e);
		if (!set.remove(o)) {
			throw new SpoonException("Element was contained in the Set, but Set#remove returned false. Not removed??");
		}
		return true;
	}

	@Override
	public boolean containsAll(Collection c) {
		return set.containsAll(c);
	}

	@Override
	public void clear() {
		if (set.isEmpty()) {
			return;
		}
		getModelChangeListener().onSetDeleteAll(getOwner(), getRole(), set, new LinkedHashSet<>(set));
		set.clear();
	}

	@Override
	public boolean equals(Object o) {
		return set.equals(o);
	}

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

	@Override
	public Iterator iterator() {
		return new Itr();
	}

	private class Itr implements Iterator {
		final Iterator delegate;
		T lastReturned = null;
		Itr() {
			delegate = set.iterator();
		}
		@Override
		public boolean hasNext() {
			return delegate.hasNext();
		}
		@Override
		public T next() {
			lastReturned = delegate.next();
			return lastReturned;
		}
		@Override
		public void remove() {
			ModelSet.this.remove(lastReturned);
		}
	}

	private FineModelChangeListener getModelChangeListener() {
		return getOwner().getFactory().getEnvironment().getModelChangeListener();
	}

	public void set(Collection elements) {
		//TODO the best would be to detect added/removed statements and to fire modifications only for them
		this.clear();
		if (elements != null && !elements.isEmpty()) {
			this.addAll(elements);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy