1   package com.stateofflow.eclipse.metrics;
2   
3   import static com.stateofflow.eclipse.metrics.MetricsPlugin.*;
4   
5   import java.io.IOException;
6   import java.util.Map;
7   
8   import org.eclipse.core.resources.IProject;
9   import org.eclipse.core.resources.IResource;
10  import org.eclipse.core.resources.IResourceDelta;
11  import org.eclipse.core.resources.IncrementalProjectBuilder;
12  import org.eclipse.core.runtime.CoreException;
13  import org.eclipse.core.runtime.IProgressMonitor;
14  import org.eclipse.core.runtime.IStatus;
15  import org.eclipse.core.runtime.Status;
16  import org.eclipse.jdt.core.IJavaProject;
17  
18  import com.stateofflow.eclipse.metrics.builder.list.CompilationUnitList;
19  import com.stateofflow.eclipse.metrics.builder.list.CompilationUnitListFactory;
20  import com.stateofflow.eclipse.metrics.export.Exporter;
21  import com.stateofflow.eclipse.metrics.util.ProgressMonitor;
22  
23  public final class MetricsBuilder extends IncrementalProjectBuilder {
24      public static final String BUILDER_ID = "com.stateofflow.eclipse.metrics.MetricsBuilder";
25      public static final String MARKER_ID = "com.stateofflow.eclipse.metrics.MetricsMarker";
26  
27      @Override
28      protected IProject[] build(final int kind, final Map args, final IProgressMonitor monitor) throws CoreException {
29          try {
30              return buildProtected(kind, monitor);
31          } catch (final CoreException cex) {
32              throw cex;
33          } catch (final Exception ex) {
34              throw new CoreException(new Status(IStatus.ERROR, MetricsPlugin.PLUGIN_ID, 0, "Exception during build: " + ex.getMessage(), ex));
35          }
36      }
37  
38      private IProject[] buildProtected(final int kind, final IProgressMonitor monitor) throws Exception {
39          switch (kind) {
40              case IncrementalProjectBuilder.AUTO_BUILD : {
41                  doAutoBuild(monitor);
42                  return null;
43              }
44              case IncrementalProjectBuilder.FULL_BUILD : {
45                  doFullBuild(monitor);
46                  return null;
47              }
48              case IncrementalProjectBuilder.INCREMENTAL_BUILD : {
49                  doMarkingBuildWithResourceDelta(monitor, getDelta(getProject()));
50                  return null;
51              }
52              default : {
53                  throw new IllegalArgumentException("Unknown build kind:" + kind);
54              }
55          }
56      }
57  
58      private void doAutoBuild(final IProgressMonitor monitor) throws Exception {
59          doAutoBuild(monitor, getDelta(getProject()));
60      }
61  
62      private void doAutoBuild(final IProgressMonitor monitor, final IResourceDelta resourceDelta) throws Exception {
63          if (resourceDelta == null) {
64              doFullBuild(monitor);
65          } else {
66              doMarkingBuildWithResourceDelta(monitor, resourceDelta);
67          }
68      }
69  
70      private void doMarkingBuildWithResourceDelta(final IProgressMonitor progressMonitor, final IResourceDelta resourceDelta) throws Exception {
71          new ProgressMonitor(progressMonitor, "Partial build", 2).run(new ProgressMonitor.Runnable() {
72              public void run(final ProgressMonitor monitor) throws CoreException, IOException {
73                  final CompilationUnitList compilationUnitList = createResourceDeltaCompilationUnitList(monitor.newChild(1), resourceDelta);
74                  doMarkingBuild(compilationUnitList, monitor.newChild(1));
75              }
76          });
77      }
78  
79      private void doFullBuild(final IProgressMonitor progressMonitor) throws Exception {
80          new ProgressMonitor(progressMonitor, "Full build", 3).run(new ProgressMonitor.Runnable() {
81              public void run(final ProgressMonitor monitor) throws CoreException, IOException {
82                  monitor.subTask("Deleting existing markers");
83                  getProject().deleteMarkers(MetricsBuilder.MARKER_ID, true, IResource.DEPTH_INFINITE);
84                  monitor.worked(1);
85                  final CompilationUnitList compilationUnitList = createFullCompilationUnitList(getProject(), monitor.newChild(1));
86                  doMarkingBuild(compilationUnitList, monitor.newChild(1));
87              }
88          });
89      }
90  
91      private void doMarkingBuild(final CompilationUnitList compilationUnits, final ProgressMonitor monitor) throws CoreException, IOException {
92          getFactory().createMarkingMetricProcessor().process(compilationUnits, monitor);
93      }
94  
95      public void export(final IProject project, final Exporter[] exporters, final IProgressMonitor progressMonitor) throws Exception {
96          new ProgressMonitor(progressMonitor, "Exporting", 2).run(new ProgressMonitor.Runnable() {
97              public void run(final ProgressMonitor monitor) throws CoreException, IOException {
98                  final CompilationUnitList compilationUnitList = createFullCompilationUnitList(project, monitor.newChild(1));
99                  getFactory().createExportingMetricProcessor(exporters).process(compilationUnitList, monitor.newChild(1));
100             }
101         });
102     }
103 
104     public void export(final CompilationUnitList compilationUnitList, final Exporter[] exporters, final IProgressMonitor progressMonitor) throws Exception {
105         new ProgressMonitor(progressMonitor, "Exporting", 1).run(new ProgressMonitor.Runnable() {
106             public void run(final ProgressMonitor monitor) throws CoreException, IOException {
107                 getFactory().createExportingMetricProcessor(exporters).process(compilationUnitList, monitor);
108             }
109         });
110     }
111 
112     private CompilationUnitList createFullCompilationUnitList(final IProject project, final ProgressMonitor monitor) throws CoreException, IOException {
113         return getCompilationUnitListFactory().createFullCompilationUnitList(getJavaProject(project), monitor);
114     }
115 
116     private CompilationUnitList createResourceDeltaCompilationUnitList(final ProgressMonitor monitor, final IResourceDelta resourceDelta) throws CoreException, IOException {
117         return getCompilationUnitListFactory().createResourceDeltaCompilationUnitList(getJavaProject(getProject()), resourceDelta, monitor);
118     }
119 
120     private CompilationUnitListFactory getCompilationUnitListFactory() {
121         return new CompilationUnitListFactory();
122     }
123 
124     private IJavaProject getJavaProject(final IProject project) {
125         return getFactory().createJavaProject(project);
126     }
127 }
128