package org.eclipse.xtext.xdoc.resource;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.IReferenceDescription;
import org.eclipse.xtext.resource.IResourceDescription;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.resource.IResourceDescription.Delta;
import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionManager;
import org.eclipse.xtext.xdoc.xdoc.XdocPackage;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
public class XdocResourceDescriptionManager extends DefaultResourceDescriptionManager {
@Override
public boolean isAffected(Collection<Delta> deltas,
IResourceDescription candidate, IResourceDescriptions context) {
if(!candidate.getURI().lastSegment().endsWith(".xdoc"))
return false;
if(super.isAffected(deltas, candidate, context) || candidate.getExportedObjectsByType(XdocPackage.Literals.DOCUMENT).iterator().hasNext()){
return true;
}
Collection<IResourceDescription> deltaDescriptions = Collections2.transform(deltas, new Function<Delta, IResourceDescription>(){
public IResourceDescription apply(Delta from) {
return from.getNew() != null? from.getNew(): from.getOld();
}
});
for (IResourceDescription rd : deltaDescriptions){
Set<QualifiedName> exportedNames = Sets.newHashSet(Iterables.transform(rd.getExportedObjects(),
new Function<IEObjectDescription, QualifiedName>(){
public QualifiedName apply(IEObjectDescription from) {
return from.getName();
}
}));
if(desc(exportedNames, candidate, context, new HashSet<IResourceDescription>()))
return true;
}
return false;
}
@Override
public boolean isAffected(Delta delta, IResourceDescription candidate)
throws IllegalArgumentException {
Iterable<IEObjectDescription> desc = candidate.getExportedObjectsByType(XdocPackage.Literals.DOCUMENT);
return super.isAffected(delta, candidate) || desc.iterator().hasNext();
}
private boolean desc(Set<QualifiedName> exportedNames, IResourceDescription cand, IResourceDescriptions context, Collection<IResourceDescription> checked) {
checked.add(cand);
if(!Collections.disjoint(exportedNames, Sets.newHashSet(cand.getImportedNames()))){
return true;
} else if(cand.getExportedObjectsByType(XdocPackage.Literals.DOCUMENT).iterator().hasNext()) {
return false;
} else {
for (IReferenceDescription referenceDescription: cand.getReferenceDescriptions()) {
EReference eReference = referenceDescription.getEReference();
if(eReference!= null) {
EClassifier eType = eReference.getEType();
if(eType == XdocPackage.Literals.CHAPTER_REF || eType == XdocPackage.Literals.SECTION_REF || eType == XdocPackage.Literals.SECTION2_REF
|| eType == XdocPackage.Literals.CODE_BLOCK) {
URI targetFile = referenceDescription.getTargetEObjectUri().trimFragment();
IResourceDescription nextCand = context.getResourceDescription(targetFile);
if(!checked.contains(nextCand))
if(desc(exportedNames, nextCand, context, checked))
return true;
}
}
}
return false;
}
}
}