001    package org.hackystat.sensorbase.resource.projects;
002    
003    import javax.xml.datatype.XMLGregorianCalendar;
004    
005    import org.hackystat.utilities.tstamp.Tstamp;
006    import org.hackystat.sensorbase.resource.sensorbase.SensorBaseResource;
007    import org.restlet.Context;
008    import org.restlet.data.Request;
009    import org.restlet.data.Response;
010    import org.restlet.resource.Representation;
011    import org.restlet.resource.Variant;
012    
013    /**
014     * The resource for processing GET host/project/{email}/{projectname}/summary.
015     * Returns a representation of the ProjectSummary resource associated with this project.
016     * The user can either specify a start and end time, which returns a ProjectSummary, or 
017     * a start time and number of days, which will return a MultDayProjectSummary. 
018     * 
019     * @author Philip Johnson
020     */
021    public class UserProjectSummaryResource extends SensorBaseResource {
022      
023      /** To be retrieved from the URL. */
024      private String startTime;
025      /** To be retrieved from the URL. */
026      private String endTime;
027      /** To be retrieved from the URL. */
028      private String numDays;
029      
030      
031      /**
032       * Provides the following representational variants: TEXT_XML.
033       * @param context The context.
034       * @param request The request object.
035       * @param response The response object.
036       */
037      public UserProjectSummaryResource(Context context, Request request, Response response) {
038        super(context, request, response);
039        this.startTime = (String) request.getAttributes().get("startTime");
040        this.endTime = (String) request.getAttributes().get("endTime");
041        this.numDays = (String) request.getAttributes().get("numDays");
042      }
043      
044      /**
045       * Returns an XML representation of the ProjectSummary associated with this User.
046       * <ul>
047       * <li> The uriUser must be defined as a User.
048       * <li> The Project must be defined for this User.
049       * <li> The authenticated user must be the admin, or uriUser, or a member of the project, or 
050       * invited to be in the Project.
051       * <li> There must be a startTime and endTime parameters which are timestamps. 
052       * </ul>
053       * 
054       * @param variant The representational variant requested, or null if conditions are violated.
055       * @return The representation. 
056       */
057      @Override
058      public Representation represent(Variant variant) {
059        if (!validateUriUserIsUser() ||
060            !validateUriProjectName() ||
061            !validateProjectViewer()) {
062          return null;
063        }  
064        
065        XMLGregorianCalendar startTimeXml = null;
066        XMLGregorianCalendar endTimeXml = null;
067        Integer numDaysInt = null;
068        // Parse this.startTime, this.endTime, and this.numDays
069        try {
070          startTimeXml = Tstamp.makeTimestamp(this.startTime);
071        }
072        catch (Exception e) {
073          setStatusBadTimestamp(this.startTime);
074          return null;
075        }
076        try {
077          if (this.endTime != null) {
078            endTimeXml = Tstamp.makeTimestamp(this.endTime);
079          }
080        }
081        catch (Exception e) {
082          setStatusBadTimestamp(this.endTime);
083          return null;
084        }
085        try {
086          if (this.numDays != null) {      
087            numDaysInt = Integer.valueOf(this.numDays);
088          }
089        }
090        catch (Exception e) {
091          setStatusMiscError("numDays parameter not an integer: " + this.numDays);      
092        }
093    
094        // Make sure that startTime is not less than project.startTime.
095        if (!ProjectUtils.isValidStartTime(project, startTimeXml)) {
096          setStatusMiscError(String.format("%s cannot be less than project start time of %s", 
097              startTimeXml, project.getStartTime()));
098          return null;
099        }
100        try {
101          // Result will hold the return value as a string.  
102          String result;
103          // First, deal with case where we have a start day and end day in URI string. 
104          // In this case we have to do additional argument validation. 
105          if (this.numDays == null) { 
106            if (Tstamp.greaterThan(startTimeXml, endTimeXml)) {
107              setStatusMiscError("startTime cannot be greater than endTime.");
108              return null;
109            }
110            // And that endTime is not past the project endTime (if there is a project endTime).
111            if ((project.getEndTime() != null) && 
112                (!ProjectUtils.isValidEndTime(project, endTimeXml))) {
113              setStatusMiscError(String.format("%s cannot be greater than project end time of %s", 
114                  endTimeXml, project.getEndTime()));
115              return null;
116            }
117            result = super.projectManager.getProjectSummaryString(project, startTimeXml, endTimeXml);
118          }
119          // Otherwise, deal with the "numDays" URI string. 
120          else {
121            result = projectManager.getMultiDayProjectSummaryString(project, startTimeXml, numDaysInt);
122          }
123          return super.getStringRepresentation(result);
124        }
125        catch (Exception e) {
126          setStatusInternalError(e);
127        }
128        return null;
129      }
130    }