001 package org.hackystat.sensorbase.db; 002 003 import java.util.List; 004 import java.util.Set; 005 import java.util.logging.Logger; 006 007 import javax.xml.datatype.XMLGregorianCalendar; 008 009 import org.hackystat.sensorbase.resource.projects.ProjectManager; 010 import org.hackystat.sensorbase.resource.projects.jaxb.Project; 011 import org.hackystat.sensorbase.resource.projects.jaxb.ProjectSummary; 012 import org.hackystat.sensorbase.resource.sensordata.SensorDataManager; 013 import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorData; 014 import org.hackystat.sensorbase.resource.sensordatatypes.SdtManager; 015 import org.hackystat.sensorbase.resource.sensordatatypes.jaxb.SensorDataType; 016 import org.hackystat.sensorbase.resource.users.UserManager; 017 import org.hackystat.sensorbase.resource.users.jaxb.User; 018 import org.hackystat.sensorbase.server.Server; 019 020 /** 021 * Provides a specification of the operations that must be implemented by every 022 * SensorBase storage system. Also provides some 'helper' methods, which return 023 * the Managers for the various resources. 024 * @author Philip Johnson 025 */ 026 public abstract class DbImplementation { 027 028 /** 029 * To be called as part of the startup process for a storage system. This method should: 030 * <ul> 031 * <li> Check to see if this storage system has already been created during a previous session. 032 * <li> If no storage system exists, it should create one and initialize it appropriately. 033 * </ul> 034 */ 035 public abstract void initialize(); 036 037 /** 038 * Returns true if the initialize() method did indeed create a fresh storage system. 039 * This is used by the ResourceManagers to determine if they should read in default data or not. 040 * @return True if the storage system is freshly created. 041 */ 042 public abstract boolean isFreshlyCreated(); 043 044 /** 045 * Returns the XML SensorDataIndex for all sensor data in this server. 046 * @return The XML String containing an index to all Sensor Data. 047 */ 048 public abstract String getSensorDataIndex(); 049 050 /** 051 * Returns the XML SensorDataIndex for all sensor data for this user. 052 * @param user The User whose sensor data is to be returned. 053 * @return The XML String providing an index of all relevent sensor data resources. 054 */ 055 public abstract String getSensorDataIndex(User user); 056 057 /** 058 * Returns the XML SensorDataIndex for all sensor data for this user and sensor data type. 059 * @param user The User whose sensor data is to be returned. 060 * @param sdtName The sensor data type name. 061 * @return The XML String providing an index of all relevent sensor data resources. 062 */ 063 public abstract String getSensorDataIndex(User user, String sdtName); 064 065 /** 066 * Returns an XML SensorDataIndex representing the SensorData for the given user between 067 * start and end time whose resource string matches at least one of the UriPatterns. 068 * @param users The list of users whose SensorData will be returned. 069 * @param startTime The earliest Sensor Data to be returned. 070 * @param endTime The latest SensorData to be returned. 071 * @param uriPatterns At least one UriPattern must match the SensorData resource field. 072 * @param sdt The SDT of interest, or null if data from all SDTs should be retrieved. 073 * @return An XML String containing a SensorDataIndex of matching SensorData. 074 */ 075 public abstract String getSensorDataIndex(List<User> users, XMLGregorianCalendar startTime, 076 XMLGregorianCalendar endTime, List<String> uriPatterns, String sdt); 077 078 /** 079 * Returns an XML SensorDataIndex representing the SensorData for the given user between 080 * start and end time whose resource string matches at least one of the UriPatterns. 081 * @param users The list of users whose SensorData will be returned. 082 * @param startTime The earliest Sensor Data to be returned. 083 * @param endTime The latest SensorData to be returned. 084 * @param uriPatterns At least one UriPattern must match the SensorData resource field. 085 * @param sdt The SDT of interest. Should not be null. 086 * @param tool The tool of interest. Should not be null. 087 * @return An XML String containing a SensorDataIndex of matching SensorData. 088 */ 089 public abstract String getSensorDataIndex(List<User> users, XMLGregorianCalendar startTime, 090 XMLGregorianCalendar endTime, List<String> uriPatterns, String sdt, String tool); 091 092 093 /** 094 * Returns the XML SensorDataIndex for all sensor data matching these users, start/end time, and 095 * whose resource string matches at least one in the list of UriPatterns. 096 * Client must guarantee that startTime and endTime are within Project dates, and that 097 * startIndex and maxInstances are non-negative. 098 * @param users The users. 099 * @param startTime The start time. 100 * @param endTime The end time. 101 * @param uriPatterns A list of UriPatterns. 102 * @param startIndex The starting index. 103 * @param maxInstances The maximum number of instances to return. 104 * @return The XML SensorDataIndex string corresponding to the matching sensor data. 105 */ 106 public abstract String getSensorDataIndex(List<User> users, XMLGregorianCalendar startTime, 107 XMLGregorianCalendar endTime, List<String> uriPatterns, int startIndex, int maxInstances); 108 109 110 /** 111 * Returns the XML SensorDataIndex for all sensor data for the given user that arrived 112 * at the server since the given start and end timestamps. 113 * This method uses the LastMod timestamp 114 * rather than the "regular" timestamp, and is used for real-time monitoring of data 115 * arriving at the server. 116 * @param user The user whose data is being monitored. 117 * @param lastModStartTime The beginning lastMod timestamp of interest. 118 * @param lastModEndTime The ending lastMod timestamp of interest. 119 * @return The XML SensorDataIndex for the recently arrived data based upon the lastMod tstamps. 120 */ 121 public abstract String getSensorDataIndexLastMod(User user, XMLGregorianCalendar lastModStartTime, 122 XMLGregorianCalendar lastModEndTime); 123 124 125 /** 126 * Returns an XML SensorDataIndex to sensor data for the given time interval and sdt with 127 * the most recent runtime value. This constitutes the "snapshot" of the data with the given 128 * sdt. If the tool parameter is null, then the last runtime snapshot is returned without regard 129 * to the tool. 130 * @param users The list of users whose sensor data will be checked. 131 * @param startTime The start time. 132 * @param endTime The end time. 133 * @param uriPatterns The uripatterns that must match the resource string. 134 * @param sdt The sensor data type of interest. 135 * @param tool The tool of interest, or null if any tool is OK. 136 * @return A string containing the XML representation of the SensorDataIndex for this snapshot. 137 */ 138 public abstract String getProjectSensorDataSnapshot(List<User> users, XMLGregorianCalendar 139 startTime, XMLGregorianCalendar endTime, List<String> uriPatterns, String sdt, String tool); 140 141 /** 142 * Returns the SensorData instance as XML string, or null if not found. 143 * @param user The user. 144 * @param timestamp The timestamp associated with this sensor data. 145 * @return The SensorData XML string, or null. 146 */ 147 public abstract String getSensorData(User user, XMLGregorianCalendar timestamp); 148 149 /** 150 * Returns true if the passed [key, timestamp] has sensor data defined for it. 151 * @param user The user. 152 * @param timestamp The timestamp 153 * @return True if there is any sensor data for this [key, sdtName, timestamp]. 154 */ 155 public abstract boolean hasSensorData(User user, XMLGregorianCalendar timestamp); 156 157 /** 158 * Persists a SensorData instance. If SensorData with this [email, timestamp] 159 * already exists in the storage system, it should be overwritten. 160 * @param data The sensor data. 161 * @param xmlSensorData The SensorData marshalled into an XML String. 162 * @param xmlSensorDataRef The corresponding SensorDataRef marshalled into an XML String 163 * @return True if the sensor data was successfully inserted. 164 */ 165 public abstract boolean storeSensorData(SensorData data, String xmlSensorData, 166 String xmlSensorDataRef); 167 168 169 /** 170 * Ensures that sensor data with the given user and timestamp is no longer 171 * present in this manager. 172 * @param user The user. 173 * @param timestamp The timestamp associated with this sensor data. 174 */ 175 public abstract void deleteSensorData(User user, XMLGregorianCalendar timestamp); 176 177 /** 178 * Ensures that sensor data with the given user is no longer present in this manager. 179 * @param user The user. 180 */ 181 public abstract void deleteSensorData(User user); 182 183 /** 184 * Returns the XML SensorDataTypeIndex for all SDTs in this server. 185 * @return The XML String containing an index to all SensorDataTypes. 186 */ 187 public abstract String getSensorDataTypeIndex(); 188 189 /** 190 * Returns the SensorDataType instance as XML string, or null if not found. 191 * @param sdtName The SDT name. 192 * @return The SensorDataType XML string, or null. 193 */ 194 public abstract String getSensorDataType(String sdtName); 195 196 197 /** 198 * Persists a SensorDataType instance. If a SensorDataType with this name 199 * already exists in the storage system, it will be overwritten. 200 * @param sdt The sensor data type 201 * @param xmlSensorDataType The SensorDataType marshalled into an XML String. 202 * @param xmlSensorDataTypeRef The corresponding SensorDataTypeRef marshalled into an XML String 203 * @return True if the SDT was successfully inserted. 204 */ 205 public abstract boolean storeSensorDataType(SensorDataType sdt, String xmlSensorDataType, 206 String xmlSensorDataTypeRef); 207 208 /** 209 * Ensures that the SensorDataType with the given name is no longer present in this manager. 210 * @param sdtName The SDT name. 211 */ 212 public abstract void deleteSensorDataType(String sdtName); 213 214 /** 215 * Returns the XML UserIndex for all Users in this server. 216 * @return The XML String containing an index to all Users. 217 */ 218 public abstract String getUserIndex(); 219 220 /** 221 * Returns the User instance as XML string, or null if not found. 222 * @param email The user's email. 223 * @return The User XML string, or null. 224 */ 225 public abstract String getUser(String email); 226 227 /** 228 * Persists a User instance. If a User with this name 229 * already exists in the storage system, it will be overwritten. 230 * @param user The user 231 * @param xmlUser The User marshalled into an XML String. 232 * @param xmlUserRef The corresponding UserRef marshalled into an XML String 233 * @return True if the user was successfully inserted. 234 */ 235 public abstract boolean storeUser(User user, String xmlUser, String xmlUserRef); 236 237 /** 238 * Ensures that the User with the given email is no longer present in this manager. 239 * @param email The user's email address. 240 */ 241 public abstract void deleteUser(String email); 242 243 /** 244 * Returns the XML ProjectIndex for all Projects in this server. 245 * @return The XML String containing an index to all Projects. 246 */ 247 public abstract String getProjectIndex(); 248 249 /** 250 * Returns the Project instance as XML string, or null if not found. 251 * @param owner The user who owns the project. 252 * @param projectName The name of the Project. 253 * @return The Project XML string, or null. 254 */ 255 public abstract String getProject(User owner, String projectName); 256 257 /** 258 * Persists a Project instance. If a Project with this owner and name 259 * already exists in the storage system, it will be overwritten. 260 * @param project The Project. 261 * @param xmlProject The Project marshalled into an XML String. 262 * @param xmlProjectRef The corresponding ProjectRef marshalled into an XML String 263 * @return True if the user was successfully inserted. 264 */ 265 public abstract boolean storeProject(Project project, String xmlProject, String xmlProjectRef); 266 267 /** 268 * Ensures that the Project with the given owner and projectName is no longer present in the db. 269 * @param owner The User who owns this project. 270 * @param projectName The name of the Project. 271 */ 272 public abstract void deleteProject(User owner, String projectName); 273 274 /** 275 * Returns a ProjectSummary instance constructed for the given Project between the startTime 276 * and endTime. This summary provides a breakdown of the number of sensor data instances found 277 * of the given type during the given time period. 278 * @param users The users in this project. 279 * @param startTime The startTime 280 * @param endTime The endTime. 281 * @param uriPatterns The UriPatterns for this project. 282 * @param href The URL naming this resource. 283 * @return The ProjectSummary instance. 284 */ 285 public abstract ProjectSummary getProjectSummary(List<User> users, XMLGregorianCalendar startTime, 286 XMLGregorianCalendar endTime, List<String> uriPatterns, String href); 287 288 289 /** Keeps a pointer to this Server for use in accessing the managers. */ 290 protected Server server; 291 292 /** Keep a pointer to the Logger. */ 293 protected Logger logger; 294 295 /** 296 * Constructs a new DbImplementation. 297 * @param server The server. 298 */ 299 public DbImplementation(Server server) { 300 this.server = server; 301 this.logger = server.getLogger(); 302 } 303 304 /** 305 * Returns the UserManager associated with this server. 306 * Since the DbManager is initialized before all other managers, we will simply 307 * get these other Managers on demand and not cache them. 308 * @return The User Manager. 309 */ 310 protected UserManager getUserManager() { 311 return (UserManager)server.getContext().getAttributes().get("UserManager"); 312 } 313 314 /** 315 * Returns the SensorDataManager associated with this server. 316 * Since the DbManager is initialized before all other managers, we will simply 317 * get these other Managers on demand and not cache them. 318 * @return The Sensor Data Manager. 319 */ 320 protected SensorDataManager getSensorDataManager() { 321 return (SensorDataManager)server.getContext().getAttributes().get("SensorDataManager"); 322 } 323 324 /** 325 * Returns the SdtManager associated with this server. 326 * Since the DbManager is initialized before all other managers, we will simply 327 * get these other Managers on demand and not cache them. 328 * @return The SdtManager. 329 */ 330 protected SdtManager getSdtManager() { 331 return (SdtManager)server.getContext().getAttributes().get("SdtManager"); 332 } 333 334 /** 335 * Returns the ProjectManager associated with this server. 336 * Since the DbManager is initialized before all other managers, we will simply 337 * get these other Managers on demand and not cache them. 338 * @return The ProjectManager. 339 */ 340 protected ProjectManager getProjectManager() { 341 return (ProjectManager)server.getContext().getAttributes().get("ProjectManager"); 342 } 343 344 345 /** 346 * Databases like Derby require an explicit compress command for releasing disk space 347 * after a large number of rows have been deleted. This operation invokes the compress 348 * command on all tables in the database. If a database implementation does not support 349 * explicit compression, then this command should do nothing but return true. 350 * @return True if the compress command succeeded or if the database does not support 351 * compression. 352 */ 353 public abstract boolean compressTables(); 354 355 /** 356 * The most appropriate set of indexes for the database has been evolving over time as we 357 * develop new queries. This command sets up the appropriate set of indexes. It should be 358 * able to be called repeatedly without error. 359 * @return True if the index commands succeeded. 360 */ 361 public abstract boolean indexTables(); 362 363 /** 364 * Returns the current number of rows in the specified table. 365 * @param table The table whose rows are to be counted. 366 * @return The number of rows in the table, or -1 if the table does not exist or an error occurs. 367 */ 368 public abstract int getRowCount(String table); 369 370 /** 371 * Returns a set containing the names of all tables in this database. Used by clients to 372 * invoke getRowCount with a legal table name. 373 * @return A set of table names. 374 */ 375 public abstract Set<String> getTableNames(); 376 377 }