001    package org.hackystat.telemetry.analyzer.reducer.impl;
002    
003    import java.util.ArrayList;
004    import java.util.List;
005    
006    import org.hackystat.dailyprojectdata.client.DailyProjectDataClient;
007    import org.hackystat.sensorbase.resource.projects.jaxb.Project;
008    import org.hackystat.sensorbase.resource.projects.jaxb.Property;
009    import org.hackystat.telemetry.analyzer.model.TelemetryStreamCollection;
010    import org.hackystat.telemetry.analyzer.reducer.TelemetryReducer;
011    import org.hackystat.telemetry.analyzer.reducer.TelemetryReducerException;
012    import org.hackystat.telemetry.service.server.ServerProperties;
013    import org.hackystat.utilities.time.interval.Interval;
014    
015    /**
016     * Returns a single stream providing Churn data.
017     * Churn is linesAdded + linesDeleted. 
018     * <p>
019     * Options:
020     * <ol>
021     * <li> isCumulative: True or false. Default is false.
022     * </ol>
023     * 
024     * @author Philip Johnson
025     */
026    public class MemberChurnReducer implements TelemetryReducer { 
027      
028      private static ChurnReducer genericChurnReducer = new ChurnReducer();
029     
030      /**
031       * Computes and returns the a set of streams providing the churn for each project member. 
032       *
033       * @param project The project.
034       * @param dpdClient The DPD Client.
035       * @param interval The interval.
036       * @param options The optional parameters.
037       *
038       * @return Telemetry stream collection.
039       * @throws TelemetryReducerException If there is any error.
040       */
041      public TelemetryStreamCollection compute(Project project, DailyProjectDataClient dpdClient, 
042          Interval interval, String[] options) throws TelemetryReducerException {
043        boolean isCumulative = false;
044        //process options
045        if (options.length > 1) {
046          throw new TelemetryReducerException("Churn reducer takes 2 optional parameters.");
047        }
048        if (options.length >= 1) {
049          try {
050            isCumulative = Boolean.valueOf(options[0]);
051          }
052          catch (Exception e) {
053            throw new TelemetryReducerException("Illegal cumulative value.", e);
054          }
055        }
056        
057        // Find out the DailyProjectData host, throw error if not found.
058        String dpdHost = System.getProperty(ServerProperties.DAILYPROJECTDATA_FULLHOST_KEY);
059        if (dpdHost == null) {
060          throw new TelemetryReducerException("Null DPD host in MemberChurnReducer");
061        }
062    
063        // now get the telemetry stream. 
064        try {
065          TelemetryStreamCollection streams = new TelemetryStreamCollection(null, project, interval);
066          // Make a list of emails containing all members plus the owner. 
067          List<String> emails = new ArrayList<String>(); 
068          emails.addAll(project.getMembers().getMember());
069          emails.add(project.getOwner());
070          // Now remove any email that has been specified as an agent.
071          for (Property property : project.getProperties().getProperty()) {
072            if (property.getKey().equals("agent")) {
073              emails.remove(property.getValue());
074            }
075          }
076          for (String email : emails) {
077            streams.add(genericChurnReducer.getStream(dpdClient, project, interval, email, 
078                isCumulative, email));
079          }
080          return streams;
081        } 
082        catch (Exception e) {
083          throw new TelemetryReducerException(e);
084        }
085      }
086    }