1   package com.stateofflow.eclipse.metrics;
2   
3   import org.eclipse.core.resources.ICommand;
4   import org.eclipse.core.resources.IProject;
5   import org.eclipse.core.resources.IProjectDescription;
6   import org.eclipse.core.resources.IProjectNature;
7   import org.eclipse.core.resources.IResource;
8   import org.eclipse.core.runtime.CoreException;
9   
10  public final class MetricsNature implements IProjectNature {
11      public static final String NATURE_ID = "com.stateofflow.eclipse.metrics.MetricsNature";
12  
13      private IProject project;
14  
15      public void configure() throws CoreException {
16          final IProjectDescription description = project.getDescription();
17          final ICommand[] commands = description.getBuildSpec();
18          if (locateBuilderInArray(commands) != -1) {
19              return;
20          }
21  
22          addBuilderToCommands(description, commands);
23      }
24  
25      private void addBuilderToCommands(final IProjectDescription description, final ICommand[] commands) throws CoreException {
26          final ICommand command = description.newCommand();
27          command.setBuilderName(MetricsBuilder.BUILDER_ID);
28          final ICommand[] newCommands = new ICommand[commands.length + 1];
29          System.arraycopy(commands, 0, newCommands, 0, commands.length);
30          newCommands[commands.length] = command;
31  
32          description.setBuildSpec(newCommands);
33          project.setDescription(description, null);
34      }
35  
36      public void deconfigure() throws CoreException {
37          removeBuilder();
38          removeMarkers();
39      }
40  
41      public void setProject(final IProject newProject) {
42          project = newProject;
43      }
44  
45      public IProject getProject() {
46          return project;
47      }
48  
49      private void removeBuilder() throws CoreException {
50          final IProjectDescription description = project.getDescription();
51          ICommand[] commands = description.getBuildSpec();
52          final int builderIndex = locateBuilderInArray(commands);
53          if (builderIndex != -1) {
54              commands = removeBuilderFromCommands(commands, builderIndex);
55              description.setBuildSpec(commands);
56              project.setDescription(description, null);
57          }
58      }
59  
60      private void removeMarkers() throws CoreException {
61          project.deleteMarkers(MetricsBuilder.MARKER_ID, true, IResource.DEPTH_INFINITE);
62      }
63  
64      private int locateBuilderInArray(final ICommand[] commands) {
65          for (int i = 0; i < commands.length; i++) {
66              if (commands[i].getBuilderName().equals(MetricsBuilder.BUILDER_ID)) {
67                  return i;
68              }
69          }
70  
71          return -1;
72      }
73  
74      private ICommand[] removeBuilderFromCommands(final ICommand[] currentCommands, final int builderIndex) {
75          final ICommand[] newCommands = new ICommand[currentCommands.length - 1];
76          if (builderIndex > 0) {
77              System.arraycopy(currentCommands, 0, newCommands, 0, builderIndex);
78          }
79  
80          if (builderIndex < currentCommands.length - 1) {
81              System.arraycopy(currentCommands, builderIndex + 1, newCommands, builderIndex, currentCommands.length - builderIndex);
82          }
83  
84          return newCommands;
85      }
86  }
87