001 package org.hackystat.sensorbase.resource.projects; 002 003 import javax.xml.datatype.XMLGregorianCalendar; 004 005 import org.hackystat.sensorbase.resource.sensorbase.SensorBaseResource; 006 import org.hackystat.utilities.tstamp.Tstamp; 007 import org.restlet.Context; 008 import org.restlet.data.MediaType; 009 import org.restlet.data.Request; 010 import org.restlet.data.Response; 011 import org.restlet.resource.Representation; 012 import org.restlet.resource.Variant; 013 014 /** 015 * The resource for processing GET host/projects/{user}/{projectname}/sensordata. 016 * Returns an index to the SensorData resources associated with this Project. 017 * This includes all of the SensorData from all members that matches the UriPattern. 018 * Note that this could be quite large if you do not also specify a start and end time. 019 * 020 * @author Philip Johnson 021 */ 022 public class UserProjectSensorDataResource extends SensorBaseResource { 023 024 /** An optional query parameter. */ 025 private String startTime; 026 /** An optional query string parameter. */ 027 private String endTime; 028 /** An optional query parameter. */ 029 private String sdt; 030 /** An optional query parameter. */ 031 private String startIndex; 032 /** An optional query parameter. */ 033 private String maxInstances; 034 /** An optional tool parameter. */ 035 private String tool; 036 037 038 /** 039 * Provides the following representational variants: TEXT_XML. 040 * @param context The context. 041 * @param request The request object. 042 * @param response The response object. 043 */ 044 public UserProjectSensorDataResource(Context context, Request request, Response response) { 045 super(context, request, response); 046 this.startTime = (String) request.getAttributes().get("startTime"); 047 this.endTime = (String) request.getAttributes().get("endTime"); 048 this.sdt = (String) request.getAttributes().get("sdt"); 049 this.startIndex = (String) request.getAttributes().get("startIndex"); 050 this.maxInstances = (String) request.getAttributes().get("maxInstances"); 051 this.tool = (String) request.getAttributes().get("tool"); 052 } 053 054 /** 055 * Returns a SensorDataIndex of all SensorData associated with this Project. This 056 * includes all SensorData from all Members in this project over the 057 * (optional) specified time period for the (optional) SDT and (optional) tool that match 058 * at least one of the UriPatterns in the project definition. 059 * 060 * Returns an error condition if: 061 * <ul> 062 * <li> The user does not exist. 063 * <li> The authenticated user is not the uriUser or the Admin or a member of the project or 064 * a spectator of the project. 065 * <li> The Project Resource named by the User and Project does not exist. 066 * <li> startTime or endTime is not an XMLGregorianCalendar string. 067 * <li> One or the other but not both of startTime and endTime is provided. 068 * <li> endTime is earlier than startTime. 069 * </ul> 070 * 071 * @param variant The representational variant requested. 072 * @return The representation. 073 */ 074 @Override 075 public Representation represent(Variant variant) { 076 if (!validateUriUserIsUser() || 077 !validateUriProjectName() || 078 !validateProjectViewer()) { 079 return null; 080 } 081 082 // If startTime is provided, then both startTime and endTime must be XMLGregorianCalendars, 083 // and startTime must be <= endTime. 084 XMLGregorianCalendar startTimeXml = null; 085 XMLGregorianCalendar endTimeXml = null; 086 if (this.startTime != null) { 087 try { 088 startTimeXml = Tstamp.makeTimestamp(this.startTime); 089 endTimeXml = Tstamp.makeTimestamp(this.endTime); 090 } 091 catch (Exception e) { 092 setStatusMiscError("startTime (or endTime) is not supplied and/or is not a timestamp"); 093 return null; 094 } 095 // We have a start and end time. Make sure startTime is not greater than endTime. 096 if (Tstamp.greaterThan(startTimeXml, endTimeXml)) { 097 setStatusMiscError("startTime cannot be greater than endTime."); 098 return null; 099 } 100 // Make sure that startTime is not less than project.startTime. 101 if (!ProjectUtils.isValidStartTime(project, startTimeXml)) { 102 setStatusMiscError(String.format("%s cannot be less than project start time of %s", 103 startTimeXml, project.getStartTime())); 104 return null; 105 } 106 // And that endTime is not past the project endTime (if there is a project endTime). 107 if ((project.getEndTime() != null) && 108 (!ProjectUtils.isValidEndTime(project, endTimeXml))) { 109 setStatusMiscError(String.format("%s cannot be greater than project end time of %s", 110 endTimeXml, project.getEndTime())); 111 return null; 112 } 113 } 114 int startIndexInt = 0; 115 int maxInstancesInt = 0; 116 // Must supply both startIndex and maxInstances if either are supplied, and 117 // startIndex and maxInstances must be non-negative integers. 118 if (this.startIndex != null) { 119 try { 120 startIndexInt = Integer.parseInt(this.startIndex); 121 maxInstancesInt = Integer.parseInt(this.maxInstances); 122 if ((startIndexInt < 0) || (maxInstancesInt <= 0)) { 123 setStatusMiscError("both startIndex & maxInstances must be non-negative."); 124 return null; 125 } 126 } 127 catch (Exception e) { 128 setStatusMiscError("startIndex (or maxInstances) is not supplied or is not an integer."); 129 return null; 130 } 131 } 132 133 if (variant.getMediaType().equals(MediaType.TEXT_XML)) { 134 try { 135 if (startTime == null) { 136 // Return all sensor data for this project if no query parameters. 137 String data = super.projectManager.getProjectSensorDataIndex(this.user, project); 138 return SensorBaseResource.getStringRepresentation(data); 139 } 140 if (tool != null) { 141 // Return the tool's sensor data starting at startTime and ending with endTime. 142 String data = super.projectManager.getProjectSensorDataIndex(this.user, project, 143 startTimeXml, endTimeXml, this.sdt, this.tool); 144 return SensorBaseResource.getStringRepresentation(data); 145 146 } 147 if (startIndex == null) { 148 // Return all sensor data starting at startTime and ending with endTime. 149 String data = super.projectManager.getProjectSensorDataIndex(this.user, project, 150 startTimeXml, endTimeXml, this.sdt); 151 return SensorBaseResource.getStringRepresentation(data); 152 } 153 else { 154 // Return the data for startIndex and maxInstances. 155 String data = super.projectManager.getProjectSensorDataIndex(this.user, project, 156 startTimeXml, endTimeXml, startIndexInt, maxInstancesInt); 157 return SensorBaseResource.getStringRepresentation(data); 158 159 } 160 } 161 catch (Exception e) { 162 setStatusInternalError(e); 163 } 164 } 165 return null; 166 } 167 }