1   package com.stateofflow.eclipse.metrics.calculators.cohesion;
2   
3   import org.eclipse.core.runtime.CoreException;
4   import org.eclipse.core.runtime.NullProgressMonitor;
5   import org.eclipse.jdt.core.ICompilationUnit;
6   import org.eclipse.jdt.core.IJavaElement;
7   import org.eclipse.jdt.core.IType;
8   import org.eclipse.jdt.core.JavaModelException;
9   import org.eclipse.jdt.core.search.IJavaSearchConstants;
10  import org.eclipse.jdt.core.search.SearchEngine;
11  import org.eclipse.jdt.core.search.SearchParticipant;
12  import org.eclipse.jdt.core.search.SearchPattern;
13  import org.eclipse.jdt.core.search.SearchRequestor;
14  
15  import com.stateofflow.eclipse.metrics.calculators.Calculator;
16  import com.stateofflow.eclipse.metrics.calculators.MeasurementContext;
17  import com.stateofflow.eclipse.metrics.metric.MetricId;
18  
19  public final class LackOfCohesionInMethodsCalculator implements Calculator {
20      public static final MetricId CHIDAMBER_KEMERER_METRIC_ID = MetricId.create(LackOfCohesionInMethodsCalculator.class, "chidamberKemerer");
21      public static final MetricId HENDERSON_SELLERS_METRIC_ID = MetricId.create(LackOfCohesionInMethodsCalculator.class, "hendersonSellers");
22      public static final MetricId TOTAL_CORRELATION_METRIC_ID = MetricId.create(LackOfCohesionInMethodsCalculator.class, "totalCorrelation");
23      public static final MetricId PAIRWISE_FIELD_IRRELATION_METRIC_ID = MetricId.create(LackOfCohesionInMethodsCalculator.class, "pairwiseFieldIrrelation");
24  
25      private static final SearchPattern DECLARATIONS_SEARCH_PATTERN = SearchPattern.createPattern("*", IJavaSearchConstants.FIELD, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH);
26      private static final SearchPattern REFERENCES_SEARCH_PATTERN = SearchPattern.createPattern("*", IJavaSearchConstants.FIELD, IJavaSearchConstants.REFERENCES, SearchPattern.R_PATTERN_MATCH);
27  
28      private MeasurementContext context;
29  
30      private void collect(final SearchPattern searchPattern, final SearchRequestor requestor) throws CoreException {
31          new SearchEngine().search(searchPattern, new SearchParticipant[]{SearchEngine.getDefaultSearchParticipant()}, SearchEngine.createJavaSearchScope(new ICompilationUnit[]{context.getUnparsedCompilationUnit()}), requestor, new NullProgressMonitor());
32      }
33  
34      private DeclaredFieldResultCollector collectDeclaredFieldData() throws CoreException {
35          final DeclaredFieldResultCollector declaredFieldResultCollector = new DeclaredFieldResultCollector(context.getSource());
36          collect(LackOfCohesionInMethodsCalculator.DECLARATIONS_SEARCH_PATTERN, declaredFieldResultCollector);
37          return declaredFieldResultCollector;
38      }
39  
40      private ReferencedFieldResultCollector collectReferencedFieldData(final DeclaredFieldResultCollector declaredFields) throws CoreException {
41          final ReferencedFieldResultCollector referencedFieldResultCollector = new ReferencedFieldResultCollector(context.getSource(), declaredFields);
42  
43          if (!declaredFields.isEmpty()) {
44              collect(LackOfCohesionInMethodsCalculator.REFERENCES_SEARCH_PATTERN, referencedFieldResultCollector);
45          }
46  
47          return referencedFieldResultCollector;
48      }
49  
50      protected void doMeasurement() throws CoreException {
51          final DeclaredFieldResultCollector declaredFields = collectDeclaredFieldData();
52          final ReferencedFieldResultCollector referencedFields = collectReferencedFieldData(declaredFields);
53          measureCohesion(declaredFields, referencedFields);
54      }
55  
56      public final void measure(MeasurementContext context) throws CoreException {
57          this.context = context;
58          doMeasurement();
59          context = null;
60      }
61  
62      private void measureCohesion(final DeclaredFieldResultCollector declaredFields, final ReferencedFieldResultCollector referencedFields) throws JavaModelException {
63          if (referencedFields.isEmpty()) {
64              return;
65          }
66  
67          for (final IJavaElement element : declaredFields.getKeys()) {
68              final IType currentClass = (IType) element;
69              referencedFields.getFieldSets(currentClass).measureCohesion(currentClass, context);
70          }
71      }
72  }