Skip to content
Snippets Groups Projects
Commit ddda1629 authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

Document-based app

parent c0ef8575
Branches
No related tags found
No related merge requests found
Showing
with 697 additions and 71 deletions
...@@ -18,6 +18,12 @@ ...@@ -18,6 +18,12 @@
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>it1901.todolist</groupId>
<artifactId>fxutil</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.openjfx/javafx-fxml --> <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-fxml -->
<dependency> <dependency>
<groupId>org.openjfx</groupId> <groupId>org.openjfx</groupId>
...@@ -77,6 +83,21 @@ ...@@ -77,6 +83,21 @@
</plugins> </plugins>
</build> </build>
</profile> </profile>
<profile>
<id>documentapp</id>
<build>
<plugins>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.4</version>
<configuration>
<mainClass>todolist.ui.TodoDocumentApp</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles> </profiles>
<build> <build>
......
...@@ -10,7 +10,7 @@ public class TodoApp extends Application { ...@@ -10,7 +10,7 @@ public class TodoApp extends Application {
@Override @Override
public void start(Stage stage) throws Exception { public void start(Stage stage) throws Exception {
Parent parent = FXMLLoader.load(getClass().getResource("TodoModel.fxml")); Parent parent = FXMLLoader.load(getClass().getResource("TodoApp.fxml"));
stage.setScene(new Scene(parent)); stage.setScene(new Scene(parent));
stage.show(); stage.show();
} }
......
package todolist.ui;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import javafx.fxml.FXML;
import todolist.core.TodoItem;
import todolist.core.TodoList;
import todolist.core.TodoModel;
import todolist.json.TodoPersistence;
public class TodoAppController {
private static final String todoListWithTwoItems =
"{\"lists\":[{\"name\":\"todo\",\"items\":[{\"text\":\"item1\",\"checked\":false},{\"text\":\"item2\",\"checked\":true,\"deadline\":\"2020-10-01T14:53:11\"}]}]}";
@FXML
String userTodoModelPath;
@FXML
String sampleTodoModelResource;
@FXML
TodoModelController todoModelViewController;
private TodoModel getInitialTodoModel() {
// setter opp data
Reader reader = null;
// try to read file from home folder first
if (userTodoModelPath != null) {
try {
reader = new FileReader(Paths.get(System.getProperty("user.home"), userTodoModelPath)
.toFile(), StandardCharsets.UTF_8);
} catch (IOException ioex) {
System.err.println("Fant ingen " + userTodoModelPath + " på hjemmeområdet");
}
}
if (reader == null && sampleTodoModelResource != null) {
// try sample todo list from resources instead
URL url = getClass().getResource(sampleTodoModelResource);
if (url != null) {
try {
reader = new InputStreamReader(url.openStream(), StandardCharsets.UTF_8);
} catch (IOException e) {
System.err.println("Kunne ikke lese innebygget " + sampleTodoModelResource);
}
} else {
System.err.println("Fant ikke innebygget " + sampleTodoModelResource);
}
}
if (reader == null) {
// use embedded String
reader = new StringReader(todoListWithTwoItems);
}
TodoModel todoModel = null;
try {
TodoPersistence todoPersistence = new TodoPersistence();
todoModel = todoPersistence.readTodoModel(reader);
} catch (IOException e) {
// ignore
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
// ignore
}
}
if (todoModel == null) {
todoModel = new TodoModel();
TodoList todoList = new TodoList(
new TodoItem().text("Øl"),
new TodoItem().text("Pizza")
);
todoModel.addTodoList(todoList);
}
return todoModel;
}
@FXML
void initialize() {
todoModelViewController.setTodoModel(getInitialTodoModel());
}
}
package todolist.ui;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class TodoDocumentApp extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent parent = FXMLLoader.load(getClass().getResource("TodoDocumentApp.fxml"));
stage.setScene(new Scene(parent));
stage.show();
}
public static void main(String[] args) {
launch(TodoDocumentApp.class, args);
}
}
\ No newline at end of file
package todolist.ui;
import fxutil.doc.FileMenuController;
import fxutil.doc.DocumentListener;
import java.io.File;
import javafx.fxml.FXML;
import todolist.core.TodoModel;
public class TodoDocumentAppController extends FileMenuController implements DocumentListener<TodoModel, File> {
private final TodoModelStorage todoModelStorage;
public TodoDocumentAppController() {
todoModelStorage = new TodoModelStorage();
todoModelStorage.addDocumentStorageListener(this);
}
public TodoModel getTodoModel() {
return todoModelStorage.getDocument();
}
// to make it testable
void setTodoModel(final TodoModel todoModel) {
todoModelStorage.setDocument(todoModel);
todoModelViewController.setTodoModel(getTodoModel());
}
@FXML
String userTodoModelPath;
@FXML
String sampleTodoModelResource;
@FXML
TodoModelController todoModelViewController;
@FXML
private void initialize() {
setDocumentStorage(todoModelStorage);
}
// DocumentListener
@Override
public void documentLocationChanged(final File documentLocation, final File oldDocumentLocation) {
}
@Override
public void documentChanged(final TodoModel document, final TodoModel oldDocument) {
todoModelViewController.setTodoModel(getTodoModel());
}
}
...@@ -38,7 +38,7 @@ public class TodoListController { ...@@ -38,7 +38,7 @@ public class TodoListController {
* Sets the TodoList managed by this controller. * Sets the TodoList managed by this controller.
* The corresponding views will be updated. * The corresponding views will be updated.
* *
* @param todoList * @param todoList the TodoList
*/ */
public void setTodoList(TodoList todoList) { public void setTodoList(TodoList todoList) {
if (this.todoList != null) { if (this.todoList != null) {
......
package todolist.ui; package todolist.ui;
import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer; import java.io.Writer;
import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
...@@ -17,16 +12,12 @@ import javafx.fxml.FXML; ...@@ -17,16 +12,12 @@ import javafx.fxml.FXML;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell; import javafx.scene.control.ListCell;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import todolist.core.TodoItem;
import todolist.core.TodoList; import todolist.core.TodoList;
import todolist.core.TodoModel; import todolist.core.TodoModel;
import todolist.json.TodoPersistence; import todolist.json.TodoPersistence;
public class TodoModelController { public class TodoModelController {
private static final String todoListWithTwoItems =
"{\"lists\":[{\"name\":\"todo\",\"items\":[{\"text\":\"item1\",\"checked\":false},{\"text\":\"item2\",\"checked\":true,\"deadline\":\"2020-10-01T14:53:11\"}]}]}";
private TodoModel todoModel; private TodoModel todoModel;
private TodoPersistence todoPersistence = new TodoPersistence(); private TodoPersistence todoPersistence = new TodoPersistence();
...@@ -43,65 +34,19 @@ public class TodoModelController { ...@@ -43,65 +34,19 @@ public class TodoModelController {
@FXML @FXML
TodoListController todoListViewController; TodoListController todoListViewController;
private void initializeTodoModel() { public void setTodoModel(TodoModel todoModel) {
// setter opp data this.todoModel = todoModel;
Reader reader = null; updateTodoListsView(null);
// try to read file from home folder first
if (userTodoListPath != null) {
try {
reader = new FileReader(Paths.get(System.getProperty("user.home"), userTodoListPath)
.toFile(), StandardCharsets.UTF_8);
} catch (IOException ioex) {
System.err.println("Fant ingen " + userTodoListPath + " på hjemmeområdet");
}
}
if (reader == null && sampleTodoListResource != null) {
// try sample todo list from resources instead
URL url = getClass().getResource(sampleTodoListResource);
if (url != null) {
try {
reader = new InputStreamReader(url.openStream(), StandardCharsets.UTF_8);
} catch (IOException e) {
System.err.println("Kunne ikke lese innebygget " + sampleTodoListResource);
}
} else {
System.err.println("Fant ikke innebygget " + sampleTodoListResource);
}
}
if (reader == null) {
// use embedded String
reader = new StringReader(todoListWithTwoItems);
}
try {
todoModel = todoPersistence.readTodoModel(reader);
} catch (IOException e) {
todoModel = new TodoModel();
TodoList todoList = new TodoList(
new TodoItem().text("Øl"),
new TodoItem().text("Pizza")
);
todoModel.addTodoList(todoList);
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
// ignore
}
}
} }
@FXML @FXML
void initialize() { void initialize() {
initializeTodoModel();
// kobler data til list-controll // kobler data til list-controll
initializeTodoListsView(); initializeTodoListsView();
todoListViewController.setOnTodoListChangedCallback(todoList -> { todoListViewController.setOnTodoListChangedCallback(todoList -> {
autoSaveTodoList(); autoSaveTodoList();
return null; return null;
}); });
updateTodoListsView(null);
} }
private void initializeTodoListsView() { private void initializeTodoListsView() {
...@@ -122,7 +67,6 @@ public class TodoModelController { ...@@ -122,7 +67,6 @@ public class TodoModelController {
return listCell; return listCell;
}); });
todoListsView.setConverter(new StringConverter<TodoList>() { todoListsView.setConverter(new StringConverter<TodoList>() {
@Override @Override
public String toString(TodoList todoList) { public String toString(TodoList todoList) {
return (todoList != null ? todoList.getName() : "???"); return (todoList != null ? todoList.getName() : "???");
......
package todolist.ui;
import fxutil.doc.AbstractDocumentStorageImpl;
import fxutil.doc.DocumentImporter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Collections;
import todolist.core.TodoModel;
import todolist.json.TodoPersistence;
public class TodoModelStorage extends AbstractDocumentStorageImpl<TodoModel, File> {
private TodoModel todoModel;
@Override
protected TodoModel getDocument() {
return todoModel;
}
@Override
protected void setDocument(TodoModel todoModel) {
this.todoModel = todoModel;
}
@Override
protected TodoModel createDocument() {
return new TodoModel();
}
private TodoPersistence todoPersistence = new TodoPersistence();
@Override
public TodoModel loadDocument(InputStream inputStream) throws Exception {
try (Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
return todoPersistence.readTodoModel(reader);
}
}
@Override
public void saveDocument(TodoModel todoModel, File file) throws Exception {
try (Writer writer = new FileWriter(file, StandardCharsets.UTF_8)) {
todoPersistence.writeTodoModel(todoModel, writer);
}
}
@Override
protected InputStream toInputStream(File file) throws IOException {
return new FileInputStream(file);
}
@Override
public Collection<DocumentImporter> getDocumentImporters() {
return Collections.emptyList();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.String?>
<?import javafx.scene.layout.VBox?>
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="todolist.ui.TodoAppController">
<fx:define>
<String fx:id="userTodoLModelPath" fx:value="todomodel.json"/>
<String fx:id="sampleTodoModelResource" fx:value="sample-todomodel.json"/>
</fx:define>
<fx:include fx:id="todoModelView" source="TodoModel.fxml"/>
</VBox>
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.String?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.MenuBar?>
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="todolist.ui.TodoDocumentAppController">
<fx:define>
<String fx:id="userTodoLModelPath" fx:value="todomodel.json"/>
<String fx:id="sampleTodoModelResource" fx:value="sample-todomodel.json"/>
</fx:define>
<top>
<MenuBar>
<menus>
<fx:include fx:id="fileMenu" source="/fxutil/doc/FileMenu.fxml"/>
</menus>
</MenuBar>
</top>
<center>
<fx:include fx:id="todoModelView" source="TodoModel.fxml"/>
</center>
</BorderPane>
...@@ -12,10 +12,6 @@ ...@@ -12,10 +12,6 @@
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?> <?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="todolist.ui.TodoModelController"> <VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="todolist.ui.TodoModelController">
<fx:define>
<String fx:id="userTodoListPath" fx:value="todolist.json"/>
<String fx:id="sampleTodoListResource" fx:value="sample-todomodel.json"/>
</fx:define>
<HBox> <HBox>
<ComboBox fx:id="todoListsView"/> <ComboBox fx:id="todoListsView"/>
</HBox> </HBox>
......
...@@ -116,8 +116,9 @@ public class TodoListControllerTest extends ApplicationTest { ...@@ -116,8 +116,9 @@ public class TodoListControllerTest extends ApplicationTest {
@Test @Test
public void testDragTodoItem() { public void testDragTodoItem() {
TodoItemListCell sourceTodoItemListCell = findTodoItemListCell(0); Predicate<TodoItemListCell> draggableCell = cell -> cell.lookup(".label") != null;
TodoItemListCell targetTodoItemListCell = findTodoItemListCell(1); TodoItemListCell sourceTodoItemListCell = findTodoItemListCell(draggableCell, 0);
TodoItemListCell targetTodoItemListCell = findTodoItemListCell(draggableCell, 1);
drag(sourceTodoItemListCell).dropTo(targetTodoItemListCell); drag(sourceTodoItemListCell).dropTo(targetTodoItemListCell);
// item order is changed // item order is changed
checkTodoListItems(item2, item1); checkTodoListItems(item2, item1);
...@@ -127,10 +128,6 @@ public class TodoListControllerTest extends ApplicationTest { ...@@ -127,10 +128,6 @@ public class TodoListControllerTest extends ApplicationTest {
// utility methods // utility methods
private TodoItemListCell findTodoItemListCell(int num) {
return findTodoItemListCell(cell -> true, num);
}
private Node findNode(Predicate<Node> nodeTest, int num) { private Node findNode(Predicate<Node> nodeTest, int num) {
int count = 0; int count = 0;
for (Node node : lookup(nodeTest).queryAll()) { for (Node node : lookup(nodeTest).queryAll()) {
......
<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>it1901.todolist</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>fxutil</artifactId>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.openjfx/javafx-fxml -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>14.0.2</version>
</dependency>
<!--
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</dependency>
-->
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
<!--
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</dependency>
-->
<!-- Test with TextFX -->
<!--
<dependency>
<groupId>org.testfx</groupId>
<artifactId>testfx-core</artifactId>
<version>4.0.16-alpha</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testfx</groupId>
<artifactId>testfx-junit5</artifactId>
<version>4.0.16-alpha</version>
<scope>test</scope>
</dependency>
-->
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
-->
<!-- Run the checkstyle code quality tool -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
<!-- Run the spotbugs code quality tool -->
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
</plugin>
<!-- Configure jacoco code coverage -->
<!--
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
</plugin>
-->
</plugins>
</build>
</project>
package fxutil.doc;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
/**
* Incomplete implementation of **DocumentStorage**,
* to simplify implementing ones for specific document and location types.
* The main missing methods are for getting and setting the current document, creating an empty one
* and creating an **InputStream** from a location.
*
* @author hal
*
* @param <D> the document type
* @param <L> the location type
*/
public abstract class AbstractDocumentStorageImpl<D, L> implements DocumentStorage<L>, DocumentPersistence<D, L> {
private L documentLocation;
@Override
public L getDocumentLocation() {
return documentLocation;
}
@Override
public void setDocumentLocation(final L documentLocation) {
final L oldDocumentLocation = this.documentLocation;
this.documentLocation = documentLocation;
fireDocumentLocationChanged(oldDocumentLocation);
}
protected void setDocumentAndLocation(final D document, final L documentLocation) {
setDocument(document);
setDocumentLocation(documentLocation);
}
/**
* Returns the current document.
*
* @return the current document
*/
protected abstract D getDocument();
/**
* Sets the current document.
*
* @param document the new document
*/
protected abstract void setDocument(D document);
//
private final Collection<DocumentStorageListener<L>> documentListeners = new ArrayList<DocumentStorageListener<L>>();
@Override
public void addDocumentStorageListener(final DocumentStorageListener<L> documentStorageListener) {
documentListeners.add(documentStorageListener);
}
@Override
public void removeDocumentStorageListener(final DocumentStorageListener<L> documentStorageListener) {
documentListeners.remove(documentStorageListener);
}
protected void fireDocumentLocationChanged(final L oldDocumentLocation) {
for (final DocumentStorageListener<L> documentStorageListener : documentListeners) {
documentStorageListener.documentLocationChanged(documentLocation, oldDocumentLocation);
}
}
protected void fireDocumentChanged(final D oldDocument) {
for (final DocumentStorageListener<L> documentListener : documentListeners) {
if (documentListener instanceof DocumentListener) {
((DocumentListener<D, L>) documentListener).documentChanged(getDocument(), oldDocument);
}
}
}
/**
* Creates a new and empty document.
*
* @return the new document
*/
protected abstract D createDocument();
@Override
public void newDocument() {
setDocumentAndLocation(createDocument(), null);
}
/**
* Creates an ImportStream from a location.
*
* @param location the location
* @return the input stream
* @throws IOException when operation failed
*/
protected abstract InputStream toInputStream(L location) throws IOException;
protected InputStream toInputStream(final File location) throws IOException {
return new FileInputStream(location);
}
protected InputStream toInputStream(final URL location) throws IOException {
return location.openStream();
}
protected InputStream toInputStream(final URI location) throws IOException {
return toInputStream(location.toURL());
}
@Override
public void openDocument(final L storage) throws IOException {
try (InputStream input = toInputStream(storage)) {
setDocumentAndLocation(loadDocument(input), storage);
} catch (final Exception e) {
throw new IOException(e);
}
}
@Override
public void saveDocument() throws IOException {
try {
saveDocument(getDocument(), getDocumentLocation());
} catch (final Exception e) {
throw new IOException(e);
}
}
/**
* Save document in specified location.
*
* @param documentLocation the document location
*/
public void saveDocumentAs(final L documentLocation) throws IOException {
final L oldDocumentLocation = getDocumentLocation();
setDocumentLocation(documentLocation);
try {
saveDocument();
} catch (final IOException e) {
setDocumentLocation(oldDocumentLocation);
throw e;
}
}
public void saveCopyAs(final L documentLocation) throws Exception {
saveDocument(getDocument(), documentLocation);
}
}
package fxutil.doc;
import java.io.IOException;
import java.io.InputStream;
/**
* An interface with a method for importing domain data from a location.
* The main use is supporting an **import** action in a **File** menu.
*
* @author hal
*
*/
public interface DocumentImporter {
/**
* Loads a document from the input stream and sets it as the current document.
*
* @param inputStream the input stream
* @throws IOException when import failed
*/
public void importDocument(InputStream inputStream) throws IOException;
}
package fxutil.doc;
/**
* Listener interface for the (contents of) the (current) document of an IDocumentStorage, e.g.
* when an **open** action is performed.
*
* @author hal
*
* @param <D> the document type
* @param <L> the location type
*/
public interface DocumentListener<D, L> extends DocumentStorageListener<L> {
/**
* Notifies that the current document has changed.
*
* @param document the new document
* @param oldDocument the previous document
*/
public void documentChanged(D document, D oldDocument);
}
package fxutil.doc;
import java.io.InputStream;
/**
* An interface with a method for loading and returning a document (domain data container)
* from an InputStream.
* This allows various ways of loading or importing domain data, with different sources and formats.
*
* @author hal
*
* @param <D> the document type
*/
public interface DocumentLoader<D> {
/**
* Loads and returns a new document from an InputStream.
*
* @param inputStream the input stream
* @return the loaded document
* @throws Exception when loading failed
*/
public D loadDocument(InputStream inputStream) throws Exception;
}
package fxutil.doc;
public interface DocumentPersistence<D, L> extends DocumentLoader<D>, DocumentSaver<D, L> {
}
package fxutil.doc;
/**
* An interface with a method for saving a document (domain data container) to a location.
* This allows various ways of saving or exporting domain data, to different locations and formats.
*
* @author hal
*
* @param <D> the document type
* @param <L> the location type
*/
public interface DocumentSaver<D, L> {
/**
* Saves the provided document to the provided location.
*
* @param document the document
* @param documentLocation the document location
* @throws Exception when save failed
*/
public void saveDocument(D document, L documentLocation) throws Exception;
}
package fxutil.doc;
import java.io.IOException;
import java.util.Collection;
/**
* An interface with the methods necessary for supporting the standard File menu actions.
* The class representing the document (domain data container) is implicit in the implementation of this interface.
* The interface includes methods for getting and setting the location and creating, opening and saving the (current) document.
*
* @author hal
*
* @param <L> The type of the location, typically java.io.File.
*/
public interface DocumentStorage<L> {
/**
* Returns the current location (of the current document).
*
* @return the current location
*/
public L getDocumentLocation();
/**
* Sets the current location (of the current document), can be used by a save-as action.
*
* @param documentLocation the document location
*/
public void setDocumentLocation(L documentLocation);
/**
* Adds an IDocumentStorageListener that will be notified when the current location changes.
*
* @param documentStorageListener the document storage listener
*/
public void addDocumentStorageListener(DocumentStorageListener<L> documentStorageListener);
/**
* Removes an IDocumentStorageListener.
*
* @param documentStorageListener the document storage listener
*/
public void removeDocumentStorageListener(DocumentStorageListener<L> documentStorageListener);
/**
* Creates a new documents and sets it as the current one, can be used by a new action.
*/
public void newDocument();
/**
* Loads a documents from the provided location and sets it as the current one, can be used by an open action.
*
* @param documentLocation the document location
*/
public void openDocument(L documentLocation) throws IOException;
/**
* Saves the current document (to the current location), can be used by a save action.
*
* @throws IOException when save failed
*/
public void saveDocument() throws IOException;
/**
* Returns the set of IDocumentImporters, can be used by an import action.
*
* @return the set of IDocumentImporters
*/
public Collection<DocumentImporter> getDocumentImporters();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment