1   package com.stateofflow.eclipse.metrics.builder.list;
2   
3   import java.io.IOException;
4   
5   import org.eclipse.core.resources.IResource;
6   import org.eclipse.core.resources.IResourceDelta;
7   import org.eclipse.core.runtime.IPath;
8   import org.eclipse.jdt.core.IClasspathEntry;
9   import org.eclipse.jdt.core.IJavaElement;
10  import org.eclipse.jdt.core.IJavaProject;
11  import org.eclipse.jdt.core.JavaCore;
12  import org.eclipse.jdt.core.JavaModelException;
13  
14  import com.stateofflow.eclipse.metrics.util.ProgressMonitor;
15  
16  class ResourceDeltaListBuilder {
17      private static final String JAVA_SUFFIX = ".java";
18  
19      private final IJavaProject project;
20      private final JavaElementListBuilder javaElementListBuilder;
21  
22      public ResourceDeltaListBuilder(final IJavaProject project, final JavaElementListBuilder javaElementListBuilder) throws IOException {
23          this.project = project;
24          this.javaElementListBuilder = javaElementListBuilder;
25      }
26  
27      public void build(final IResourceDelta delta, final ProgressMonitor monitor) throws JavaModelException {
28          addTypesForResourceDelta(delta, monitor);
29      }
30  
31      private void addTypesForResourceDelta(final IResourceDelta delta, final ProgressMonitor monitor) throws JavaModelException {
32          final IResourceDelta[] affectedChildren = delta.getAffectedChildren();
33          monitor.beginTask("Adding types for resource delta: " + delta.getProjectRelativePath(), affectedChildren.length);
34          for (int i = 0; i < affectedChildren.length; i++) {
35              addTypesForAffectedResourceDelta(affectedChildren[i], monitor.newChild(1));
36          }
37      }
38  
39      private void addTypesForAffectedResourceDelta(final IResourceDelta affectedChild, final ProgressMonitor monitor) throws JavaModelException {
40          final IResource affectedResource = affectedChild.getResource();
41          if (isJavaFile(affectedResource) && isAddedOrChanged(affectedChild) && isOnClasspath(affectedResource)) {
42              addTypesForJavaElement(JavaCore.create(affectedResource), monitor.newChild(1));
43          } else if (isFolder(affectedResource)) {
44              addTypesForResourceDelta(affectedChild, monitor.newChild(1));
45          }
46      }
47  
48      private void addTypesForJavaElement(final IJavaElement element, final ProgressMonitor monitor) throws JavaModelException {
49          javaElementListBuilder.addTypesForJavaElement(element, monitor);
50      }
51  
52      private boolean isAddedOrChanged(final IResourceDelta delta) {
53          return delta.getKind() == IResourceDelta.ADDED || delta.getKind() == IResourceDelta.CHANGED;
54      }
55  
56      private boolean isFolder(final IResource resource) {
57          return resource.getType() == IResource.FOLDER;
58      }
59  
60      private boolean isJavaFile(final IResource resource) {
61          return resource.getType() == IResource.FILE && resource.getName().endsWith(JAVA_SUFFIX);
62      }
63  
64      private boolean isOnClasspath(final IResource resource) throws JavaModelException {
65          final IPath resourcePath = resource.getFullPath();
66          final IClasspathEntry[] classpath = project.getResolvedClasspath(true);
67          for (int i = 0; i < classpath.length; i++) {
68              if (classpath[i].getPath().makeRelative().isPrefixOf(resourcePath)) {
69                  return true;
70              }
71          }
72  
73          return false;
74      }
75  }
76