/*******************************************************************************
* Copyright (c) 2007, 2011 Wind River Systems, Inc. and others.
* 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.cdt.core.model.ICContainer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
public class DeltaAnalyzer {
private final List<ITranslationUnit> fForce= new ArrayList<ITranslationUnit>();
private final List<ITranslationUnit> fChanged= new ArrayList<ITranslationUnit>();
private final List<ITranslationUnit> fRemoved= new ArrayList<ITranslationUnit>();
// For testing purposes, only.
public static boolean sSuppressPotentialTUs= false;
public DeltaAnalyzer() {
}
public void analyzeDelta(ICElementDelta delta) throws CoreException {
processDelta(delta, new HashSet<IResource>());
}
private void processDelta(ICElementDelta delta, Set<IResource> handled) throws CoreException {
final int flags = delta.getFlags();
final boolean hasChildren = (flags & ICElementDelta.F_CHILDREN) != 0;
if (hasChildren) {
for (ICElementDelta child : delta.getAffectedChildren()) {
processDelta(child, handled);
}
}
final ICElement element = delta.getElement();
switch (element.getElementType()) {
case ICElement.C_UNIT:
ITranslationUnit tu = (ITranslationUnit)element;
if (!tu.isWorkingCopy()) {
handled.add(element.getResource());
switch (delta.getKind()) {
case ICElementDelta.CHANGED:
if ((flags & ICElementDelta.F_CONTENT) != 0) {
fChanged.add(tu);
}
break;
case ICElementDelta.ADDED:
fChanged.add(tu);
break;
case ICElementDelta.REMOVED:
fRemoved.add(tu);
break;
}
}
break;
case ICElement.C_CCONTAINER:
ICContainer folder= (ICContainer) element;
if (delta.getKind() == ICElementDelta.ADDED) {
handled.add(element.getResource());
collectSources(folder, fChanged);
}
break;
}
if (!sSuppressPotentialTUs) {
// Always look at the children of the resource delta (bug 343538)
final IResourceDelta[] rDeltas= delta.getResourceDeltas();
processResourceDelta(rDeltas, element, handled);
}
}
public void processResourceDelta(final IResourceDelta[] rDeltas, final ICElement element,
Set<IResource> handled) {
if (rDeltas != null) {
for (IResourceDelta rd: rDeltas) {
final int rdkind = rd.getKind();
if (rdkind != IResourceDelta.ADDED) {
IResource res= rd.getResource();
if (!handled.add(res)) {
continue;
}
if (res instanceof IFile) {
switch (rdkind) {
case IResourceDelta.CHANGED:
if ((rd.getFlags() & IResourceDelta.CONTENT) != 0) {
fChanged.add(new PotentialTranslationUnit(element, (IFile) res));
}
break;
case IResourceDelta.REMOVED:
fRemoved.add(new PotentialTranslationUnit(element, (IFile) res));
break;
}
}
}
processResourceDelta(rd.getAffectedChildren(IResourceDelta.CHANGED | IResourceDelta.REMOVED), element, handled);
}
}
}
private void collectSources(ICContainer container, Collection<ITranslationUnit> sources) throws CoreException {
container.accept(new TranslationUnitCollector(sources, sources, new NullProgressMonitor()));
}
public ITranslationUnit[] getForcedTUs() {
return fForce.toArray(new ITranslationUnit[fForce.size()]);
}
public ITranslationUnit[] getChangedTUs() {
return fChanged.toArray(new ITranslationUnit[fChanged.size()]);
}
public ITranslationUnit[] getRemovedTUs() {
return fRemoved.toArray(new ITranslationUnit[fRemoved.size()]);
}
public List<ITranslationUnit> getForcedList() {
return fForce;
}
public List<ITranslationUnit> getChangedList() {
return fChanged;
}
}