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

org.aspectj.weaver.Iterators Maven / Gradle / Ivy

Go to download

The AspectJ matcher can be used for matching pointcuts independently of any AspectJ compilation or weaving steps. Most notably, this can be used by frameworks such as Spring AOP which utilise the @AspectJ pointcut syntax but implement aspect weaving in a way independent of AspectJ, e.g. using dynamic proxies.

There is a newer version: 1.9.22.1
Show newest version
/* *******************************************************************
 * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
 * All rights reserved.
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Public License v 2.0
 * which accompanies this distribution and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
 *
 * Contributors:
 *     PARC     initial implementation
 * ******************************************************************/

package org.aspectj.weaver;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;

public final class Iterators {

	/**
	 * Private constructor, nobody should ever make one of these
	 */
	private Iterators() {
	}

	/**
	 * A getter represents a mapping function from Object to Iterator
	 */
	public interface Getter {
		Iterator get(A target);
	}

	/**
	 * A filter represents a mapping function from Iterator to Iterator
	 */
	public interface Filter {
		Iterator filter(Iterator in);
	}

	/**
	 * Create a new filter F that, when wrapped around another iterator I, creates a new iterator I' that will return only those
	 * values of I that have not yet been returned by I', discarding duplicates.
	 */
	public static  Filter dupFilter() {
		return new Filter() {
			final Set seen = new HashSet<>(); // should have weak ptrs?

			public Iterator filter(final Iterator in) {
				return new Iterator() {
					boolean fresh = false;
					T peek;

					public boolean hasNext() {
						if (fresh) {
							return true;
						}
						while (true) {
							if (!in.hasNext()) {
								return false;
							}
							peek = in.next();
							if (!seen.contains(peek)) {
								fresh = true;
								return true;
							} else {
								peek = null; // garbage collection
							}
						}
					}

					public T next() {
						if (!hasNext()) {
							throw new NoSuchElementException();
						}
						T ret = peek;
						seen.add(peek);
						peek = null;
						fresh = false;
						return ret;
					}

					public void remove() {
						throw new UnsupportedOperationException();
					}
				};
			}
		};
	}

	/**
	 * Creates an iterator that will return the elements of a specified array, in order. Like Arrays.asList(o).iterator(), without
	 * all that pesky safety.
	 */

	public static  Iterator array(final T[] o) {
		return new Iterator() {
			int i = 0;
			int len = (o == null) ? 0 : o.length;

			public boolean hasNext() {
				return i < len;
			}

			public T next() {
				if (i < len) {
					return o[i++];
				} else {
					throw new NoSuchElementException();
				}
			}

			public void remove() {
				throw new UnsupportedOperationException();
			}
		};
	}

	public static class ResolvedTypeArrayIterator implements Iterator {
		private ResolvedType[] array;
		private int index;
		private int len;
		private boolean wantGenerics;
		private List alreadySeen; // type signatures

		public ResolvedTypeArrayIterator(ResolvedType[] array, List alreadySeen, boolean wantGenerics) {
			assert array != null;
			this.array = array;
			this.wantGenerics = wantGenerics;
			this.len = array.length;
			this.index = 0;
			this.alreadySeen = alreadySeen;
			moveToNextNewOne();
		}

		private void moveToNextNewOne() {
			while (index < len) {
				ResolvedType interfaceType = array[index];
				if (!wantGenerics && interfaceType.isParameterizedOrGenericType()) {
					interfaceType = interfaceType.getRawType();
				}
				String signature = interfaceType.getSignature();
				if (!alreadySeen.contains(signature)) {
					break;
				}
				index++;
			}
		}

		public boolean hasNext() {
			return index < len;
		}

		public ResolvedType next() {
			if (index < len) {
				ResolvedType oo = array[index++];
				if (!wantGenerics && (oo.isParameterizedType() || oo.isGenericType())) {
					oo = oo.getRawType();
				}
				alreadySeen.add(oo.getSignature());
				moveToNextNewOne();
				return oo;
			} else {
				throw new NoSuchElementException();
			}
		}

		public void remove() {
			throw new UnsupportedOperationException();
		}
	}

	public static Iterator array(final ResolvedType[] o, final boolean genericsAware) {
		return new Iterator() {
			int i = 0;
			int len = (o == null) ? 0 : o.length;

			public boolean hasNext() {
				return i < len;
			}

			public ResolvedType next() {
				if (i < len) {
					ResolvedType oo = o[i++];
					if (!genericsAware && (oo.isParameterizedType() || oo.isGenericType())) {
						return oo.getRawType();
					}
					return oo;
				} else {
					throw new NoSuchElementException();
				}
			}

			public void remove() {
				throw new UnsupportedOperationException();
			}
		};
	}

	/**
	 * creates an iterator I based on a base iterator A and a getter G. I returns, in order, forall (i in A), G(i).
	 */
	public static  Iterator mapOver(final Iterator a, final Getter g) {
		return new Iterator() {
			Iterator delegate = new Iterator() {
				public boolean hasNext() {
					if (!a.hasNext()) {
						return false;
					}
					A o = a.next();
					delegate = append1(g.get(o), this);
					return delegate.hasNext();
				}

				public B next() {
					if (!hasNext()) {
						throw new UnsupportedOperationException();
					}
					return delegate.next();
				}

				public void remove() {
					throw new UnsupportedOperationException();
				}
			};

			public boolean hasNext() {
				return delegate.hasNext();
			}

			public B next() {
				return delegate.next();
			}

			public void remove() {
				throw new UnsupportedOperationException();
			}
		};
	}

	/**
	 * creates an iterator I based on a base iterator A and a getter G. I returns, in order, forall (i in I) i :: forall (i' in
	 * g(i)) recur(i', g)
	 */
	public static  Iterator recur(final A a, final Getter g) {
		return new Iterator() {
			Iterator delegate = one(a);

			public boolean hasNext() {
				return delegate.hasNext();
			}

			public A next() {
				A next = delegate.next();
				delegate = append(g.get(next), delegate);
				return next;
			}

			public void remove() {
				throw new UnsupportedOperationException();
			}
		};
	}

	/**
	 * creates an iterator I based on base iterators A and B. Returns the elements returned by A followed by those returned by B. If
	 * B is empty, simply returns A, and if A is empty, simply returns B. Do NOT USE if b.hasNext() is not idempotent.
	 */
	public static  Iterator append(final Iterator a, final Iterator b) {
		if (!b.hasNext()) {
			return a;
		}
		return append1(a, b);
	}

	/**
	 * creates an iterator I based on base iterators A and B. Returns the elements returned by A followed by those returned by B. If
	 * A is empty, simply returns B. Guaranteed not to call B.hasNext() until A is empty.
	 */
	public static  Iterator append1(final Iterator a, final Iterator b) {
		if (!a.hasNext()) {
			return b;
		}
		return new Iterator() {
			public boolean hasNext() {
				return a.hasNext() || b.hasNext();
			}

			public T next() {
				if (a.hasNext()) {
					return a.next();
				}
				if (b.hasNext()) {
					return b.next();
				}
				throw new NoSuchElementException();
			}

			public void remove() {
				throw new UnsupportedOperationException();
			}
		};
	}

	/**
	 * creates an iterator I based on a base iterator A and an object O. Returns the elements returned by A, followed by O.
	 */
	public static  Iterator snoc(final Iterator first, final T last) {
		return new Iterator() {
			T last1 = last;

			public boolean hasNext() {
				return first.hasNext() || last1 != null;
			}

			public T next() {
				if (first.hasNext()) {
					return first.next();
				} else if (last1 == null) {
					throw new NoSuchElementException();
				}
				T ret = last1;
				last1 = null;
				return ret;
			}

			public void remove() {
				throw new UnsupportedOperationException();
			}
		};
	}

	/**
	 * creates an iterator I based on an object O. Returns O, once.
	 */
	public static  Iterator one(final T it) {
		return new Iterator() {
			boolean avail = true;

			public boolean hasNext() {
				return avail;
			}

			public T next() {
				if (!avail) {
					throw new NoSuchElementException();
				}
				avail = false;
				return it;
			}

			public void remove() {
				throw new UnsupportedOperationException();
			}
		};
	}
}