blob: bde203932ad561f4bcf0a5e04bfa28e6b92bf795 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 THALES GLOBAL SERVICES.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.ext.emf;
import java.util.Iterator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
/**
* Adapter class to treat an EObject as an Iterable on all its contents.
* <p>
* Usage:
*
* <pre>
* for (EObject obj : AllContents.of(root)) {
* // code
* }
* </pre>
*
* @author pcdavid
*/
public final class AllContents implements Iterable<EObject> {
private final EObject root;
private final EClass klass;
private final boolean includeRoot;
/**
* Constructor.
*
* @param root
* the root element.
* @param klass
* the optional type of elements to find.
* @param includeRoot
* whether or not the root element itself should be included in
* the iterator.
*
*/
private AllContents(EObject root, EClass klass, boolean includeRoot) {
this.root = root;
this.klass = klass;
this.includeRoot = includeRoot;
}
/**
* Factory method.
*
* @param obj
* the root element.
* @return an iterable on all the sub-elements of the root (recursively).
*/
public static Iterable<EObject> of(EObject obj) {
return AllContents.of(obj, false);
}
/**
* Factory method.
*
* @param obj
* the root element.
* @param includeRoot
* whether or not the root element itself should be included in
* the iterator.
* @return an iterable on all the sub-elements of the root (recursively).
*/
public static Iterable<EObject> of(EObject obj, boolean includeRoot) {
return new AllContents(obj, null, includeRoot);
}
/**
* Factory method.
*
* @param obj
* the root element.
* @param klass
* the type of elements to consider.
* @return an iterable on all the sub-elements of the root (recursively)
* which are of the specified type.
*/
public static Iterable<EObject> of(EObject obj, EClass klass) {
return AllContents.of(obj, klass, false);
}
/**
* Factory method.
*
* @param obj
* the root element.
* @param klass
* the type of elements to consider.
* @param includeRoot
* whether or not the root element itself should be included in
* the iterator. * @return an iterable on all the sub-elements of
* the root (recursively) which are of the specified type.
*/
public static Iterable<EObject> of(EObject obj, EClass klass, boolean includeRoot) {
return new AllContents(obj, klass, includeRoot);
}
/**
* {@inheritDoc}
*/
public Iterator<EObject> iterator() {
final Iterator<EObject> contentsIterator;
if (root == null) {
contentsIterator = Iterators.<EObject> emptyIterator();
} else if (klass == null) {
contentsIterator = root.eAllContents();
} else {
contentsIterator = Iterators.filter(root.eAllContents(), new Predicate<EObject>() {
public boolean apply(EObject input) {
return klass.isInstance(input);
}
});
}
if (includeRoot) {
return Iterators.concat(Iterators.singletonIterator(root), contentsIterator);
} else {
return contentsIterator;
}
}
}