001package edu.pdx.cs410J.grader.gradebook; 002 003import edu.pdx.cs410J.ParserException; 004 005import java.io.File; 006import java.io.FileNotFoundException; 007import java.io.IOException; 008import java.io.PrintWriter; 009import java.time.LocalDateTime; 010 011/** 012 * This class represents an assignment give to students in CS410J. 013 * 014 * @author David Whitlock 015 */ 016public class Assignment extends NotableImpl { 017 018 public enum AssignmentType { 019 PROJECT, 020 QUIZ, 021 OTHER, 022 POA, 023 OPTIONAL 024 } 025 026 027 public enum ProjectType { 028 APP_CLASSES, 029 TEXT_FILE, 030 PRETTY_PRINT, 031 KOANS, 032 XML, 033 REST, 034 ANDROID 035 } 036 037 private final String name; 038 private String description; 039 private double points; 040 private int canvasId; 041 private AssignmentType type; 042 private LocalDateTime dueDate; 043 private ProjectType projectType; 044 045 /** 046 * Creates a new <code>Assignment</code> with the given name and 047 * point value. 048 */ 049 public Assignment(String name, double points) { 050 this.name = name; 051 this.points = points; 052 this.type = AssignmentType.PROJECT; 053 this.setDirty(false); 054 } 055 056 /** 057 * Returns the name of this <code>Assignment</code> 058 */ 059 public String getName() { 060 return this.name; 061 } 062 063 /** 064 * Returns the number of points this <code>Assignment</code> is 065 * worth 066 */ 067 public double getPoints() { 068 return this.points; 069 } 070 071 /** 072 * Sets the number of points that this <code>Assignment</code> is 073 * worth. 074 */ 075 public Assignment setPoints(double points) { 076 this.setDirty(true); 077 this.points = points; 078 return this; 079 } 080 081 /** 082 * Returns a description of this <code>Assignment</code> 083 */ 084 public String getDescription() { 085 return this.description; 086 } 087 088 /** 089 * Sets the description of this <code>Assignment</code> 090 */ 091 public Assignment setDescription(String description) { 092 this.setDirty(true); 093 this.description = description; 094 return this; 095 } 096 097 /** 098 * Returns the type of this <code>Assignment</code> 099 */ 100 public AssignmentType getType() { 101 return this.type; 102 } 103 104 /** 105 * Sets the type of this <code>Assignment</code> 106 */ 107 public Assignment setType(AssignmentType type) { 108 this.setDirty(true); 109 this.type = type; 110 return this; 111 } 112 113 114 public Assignment setCanvasId(int canvasId) { 115 this.canvasId = canvasId; 116 this.setDirty(true); 117 return this; 118 } 119 120 public int getCanvasId() { 121 return canvasId; 122 } 123 124 125 /** 126 * Returns a brief textual description of this 127 * <code>Assignment</code> 128 */ 129 public String toString() { 130 return "Assignment " + this.getName() + " worth " + 131 this.getPoints(); 132 } 133 134 135 private static PrintWriter err = new PrintWriter(System.err, true); 136 137 /** 138 * Prints usage information about the main program. 139 */ 140 private static void usage() { 141 err.println("\njava Assignment [options] -xmlFile xmlFile " + 142 "-name name"); 143 err.println(" where [options] are:"); 144 err.println(" -points points Points assignment is worth"); 145 err.println(" -description desc Description of assignment"); 146 err.println(" -type type Type of assignment " + 147 "(PROJECT, QUIZ, or OTHER)"); 148 err.println(" -note note Note about assignment"); 149 err.println("\n"); 150 System.exit(1); 151 } 152 153 /** 154 * Main program that creates/edits an <code>Assignment</code> in a 155 * grade book stored in an XML file. 156 */ 157 public static void main(String[] args) { 158 String fileName = null; 159 String name = null; 160 String points = null; 161 String desc = null; 162 AssignmentType type = null; 163 String note = null; 164 165 // Parse the command line 166 for (int i = 0; i < args.length; i++) { 167 if (args[i].equals("-xmlFile")) { 168 if (++i >= args.length) { 169 err.println("** Missing XML file name"); 170 usage(); 171 } 172 173 fileName = args[i]; 174 175 } else if (args[i].equals("-name")) { 176 if (++i >= args.length) { 177 err.println("** Missing assignment name"); 178 usage(); 179 } 180 181 name = args[i]; 182 183 } else if (args[i].equals("-points")) { 184 if (++i >= args.length) { 185 err.println("** Missing points value"); 186 usage(); 187 } 188 189 points = args[i]; 190 191 } else if (args[i].equals("-description")) { 192 if (++i >= args.length) { 193 err.println("** Missing description"); 194 usage(); 195 } 196 197 desc = args[i]; 198 199 } else if (args[i].equals("-type")) { 200 if (++i >= args.length) { 201 err.println("** Missing type"); 202 usage(); 203 } 204 205 // Make sure type is valid 206 switch (args[i]) { 207 case "PROJECT": 208 type = AssignmentType.PROJECT; 209 break; 210 case "QUIZ": 211 type = AssignmentType.QUIZ; 212 break; 213 case "POA": 214 type = AssignmentType.POA; 215 break; 216 case "OTHER": 217 type = AssignmentType.OTHER; 218 break; 219 case "OPTIONAL": 220 type = AssignmentType.OPTIONAL; 221 break; 222 default: 223 err.println("** Invalid type: " + args[i]); 224 usage(); 225 break; 226 } 227 228 } else if (args[i].equals("-note")) { 229 if (++i >= args.length) { 230 err.println("** Missing note"); 231 usage(); 232 } 233 234 note = args[i]; 235 236 } else { 237 err.println("** Unknown option: " + args[i]); 238 } 239 } 240 241 // Verify command line 242 if (fileName == null) { 243 err.println("** No file name specified"); 244 usage(); 245 } 246 247 if (name == null) { 248 err.println("** No assignment name specified"); 249 usage(); 250 } 251 252 File file = new File(fileName); 253 if (!file.exists()) { 254 err.println("** Grade book file " + fileName + 255 " does not exist"); 256 System.exit(1); 257 } 258 259 if (name == null) { 260 err.println("** No assignment name specified"); 261 usage(); 262 } 263 264 GradeBook book = null; 265 try { 266 XmlGradeBookParser parser = new XmlGradeBookParser(file); 267 book = parser.parse(); 268 269 } catch (FileNotFoundException ex) { 270 err.println("** Could not find file: " + ex.getMessage()); 271 System.exit(1); 272 273 } catch (IOException ex) { 274 err.println("** IOException during parsing: " + ex.getMessage()); 275 System.exit(1); 276 277 } catch (ParserException ex) { 278 err.println("** Exception while parsing " + file + ": " + ex); 279 System.exit(1); 280 } 281 282 // Get the assignment 283 Assignment assign = book.getAssignment(name); 284 if (assign == null) { 285 // Did we specify a points value? 286 if (points == null) { 287 err.println("** No points specified"); 288 usage(); 289 } 290 291 double value = -1.0; 292 try { 293 value = Double.parseDouble(points); 294 295 } catch (NumberFormatException ex) { 296 err.println("** Not a valid point value: " + points); 297 System.exit(1); 298 } 299 300 if (value < 0.0) { 301 err.println("** Not a valid point value: " + value); 302 System.exit(1); 303 } 304 305 // Create a new Assignment 306 assign = new Assignment(name, value); 307 book.addAssignment(assign); 308 } 309 310 // Set the properties of the assignment 311 if (desc != null) { 312 assign.setDescription(desc); 313 } 314 315 if (type != null) { 316 assign.setType(type); 317 } 318 319 if (note != null) { 320 assign.addNote(note); 321 } 322 323 // Write the grade book back out to the XML file 324 try { 325 XmlDumper dumper = new XmlDumper(file); 326 dumper.dump(book); 327 328 } catch (IOException ex) { 329 err.println("** While dumping to " + file + ": " + ex); 330 System.exit(1); 331 } 332 } 333 334 public void setDueDate(LocalDateTime dueDate) { 335 this.dueDate = dueDate; 336 } 337 338 public LocalDateTime getDueDate() { 339 return dueDate; 340 } 341 342 public boolean isSubmissionLate(LocalDateTime submissionTime) { 343 if (this.dueDate == null) { 344 return false; 345 346 } else { 347 return submissionTime.isAfter(this.dueDate); 348 } 349 } 350 351 public Assignment setProjectType(ProjectType projectType) { 352 this.projectType = projectType; 353 return this; 354 } 355 356 public ProjectType getProjectType() { 357 return projectType; 358 } 359 360}