Coverage Summary for Class: SaveManager (it.polimi.ingsw.gc14)

Class Class, % Method, % Line, %
SaveManager 0% (0/1) 0% (0/4) 0% (0/22)


 package it.polimi.ingsw.gc14;
 
 import it.polimi.ingsw.gc14.Model.Game;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.net.URISyntaxException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 
 /**
  * Handles persistence of the game model to and from disk.
  *
  * <p>The save file is stored at {@code GameSaves/save.dat} relative to the
  * directory containing the running JAR. The anchor class passed to the
  * constructor is used to resolve that directory at construction time.
  *
  * <p>All three operations ({@link #save}, {@link #load}, {@link #delete})
  * are independent and safe to call in any order; missing files are treated
  * as a normal condition (no save present) rather than an error.
  */
 public class SaveManager {
 
     /** Relative sub-path of the save file inside the JAR directory. */
     private static final String SAVE_RELATIVE_PATH = "GameSaves/save.dat";
 
     /** Absolute path of the save file, resolved once at construction. */
     private final Path filePath;
 
     /**
      * Constructs a {@code SaveManager} whose save file is located relative
      * to the JAR directory of the given anchor class.
      *
      * @param anchorClass the class whose code-source location is used as
      *                    the base directory for the save file.
      * @throws RuntimeException if the JAR path cannot be resolved.
      */
     public SaveManager(Class<?> anchorClass) {
         try {
             Path jarDir = Paths.get(
                     anchorClass.getProtectionDomain().getCodeSource().getLocation().toURI()
             ).getParent();
             this.filePath = jarDir.resolve(SAVE_RELATIVE_PATH);
         } catch (URISyntaxException e) {
             throw new RuntimeException("Could not resolve save file path", e);
         }
     }
 
     /**
      * Serializes the game model to disk, creating parent directories if needed.
      *
      * @param game the game model to persist.
      * @return {@code true} if the save succeeded, {@code false} on I/O error.
      */
     public boolean save(Game game) {
         try {
             Files.createDirectories(filePath.getParent());
             try (ObjectOutputStream oos = new ObjectOutputStream(
                     new BufferedOutputStream(new FileOutputStream(filePath.toFile())))) {
                 oos.writeObject(game);
                 return true;
             }
         } catch (IOException e) {
             e.printStackTrace();
             return false;
         }
     }
 
     /**
      * Deserializes the game model from disk.
      *
      * @return the saved {@link Game} instance, or {@code null} if no save file
      *         exists or an I/O error prevents reading.
      * @throws RuntimeException if the serialized class cannot be found on
      *                          the classpath (indicates a deployment mismatch).
      */
     public Game load() {
         try (ObjectInputStream ois = new ObjectInputStream(
                 new BufferedInputStream(new FileInputStream(filePath.toFile())))) {
             return (Game) ois.readObject();
         } catch (FileNotFoundException e) {
             return null;
         } catch (IOException e) {
             e.printStackTrace();
             return null;
         } catch (ClassNotFoundException e) {
             throw new RuntimeException("Save file references an unknown class", e);
         }
     }
 
     /**
      * Deletes the save file.
      *
      * @return {@code true} if the file was deleted, {@code false} otherwise
      *         (including when the file did not exist).
      */
     public boolean delete() {
         try {
             return Files.deleteIfExists(filePath);
         } catch (IOException e) {
             return false;
         }
     }
 }