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;
}
}
}