import java.io.*;
import java.util.StringTokenizer;

    // Demonstrate use of Object Serialization by reading and
    // writing a BookmarkCollection object.
    // Read and write to the file passed to the constructor.
    // Fail with a runtime exception if the file is inaccessible.
class BookmarkDemo {
    public BookmarkDemo(String filename) throws RuntimeException {
        this.filename = filename;
        File bookmarkFile = new File(filename);
        if(bookmarkFile.exists()){
            if(!bookmarkFile.canRead()){
                throw new RuntimeException(filename+" is unreadable.");
            }
            else if(!bookmarkFile.canWrite()){
                throw new RuntimeException(filename+" is unwriteable.");
            }
            else{
                // Ok. Read the saved collection.
                collection = readCollection();
            }
        }
        else{
            // There is no existing collection.
            collection = new BookmarkCollection();
        }
    }

        // Interactively read new bookmarks from the user.
        // The URL "quit" terminates the input.
        // Save the new state of the collection on completion.
    public void updateCollection(){
        final BookmarkCollection collection = getCollection();
        final SimpleInput reader = new SimpleInput();
        System.out.println("Supply each URL and title on a single line.");
        System.out.println(
                "Separate the URL from the title with an @ character, e.g.");
        System.out.println("http://www.javasoft.com@JavaSoft Home Page");
        System.out.println("Finish with a blank line.");
        String line = reader.nextLine();
        while(line.length() > 0){
            StringTokenizer tokenizer = new StringTokenizer(line,"@");
            final String url = tokenizer.nextToken();
            // Take the remainder of the line as the title.
            final String title = tokenizer.nextToken();
            collection.add(new Bookmark(url,title));
            line = reader.nextLine();
        }
        saveCollection();
    }

        // Print them out.
    public void printCollection(){
        Bookmark[] marks = getCollection().getBookmarks();
        for(int i = 0; i < marks.length; i++){
            final Bookmark mark = marks[i];
            System.out.println(mark.getUrl()+" "+mark.getTitle());
        }
    }

        // Try to read a Bookmark collection. Throw a RuntimeException
        // on failure.
    private BookmarkCollection readCollection() throws RuntimeException {
        try{
            final String filename = getFilename();
            // Open the input stream for the associated file.
            ObjectInputStream istream = new ObjectInputStream(
                    new FileInputStream(filename));
            BookmarkCollection collection =
                        (BookmarkCollection) istream.readObject();
            istream.close();
            return collection;
        }
        catch(Exception e){
            throw new RuntimeException("Reading failed: "+e);
        }
    }

    private void saveCollection(){
        try{
            final String filename = getFilename();
            // Open the output stream for the associated file.
            ObjectOutputStream ostream = new ObjectOutputStream(
                    new FileOutputStream(filename));
            ostream.writeObject(getCollection());
            ostream.close();
        }
        catch(NotSerializableException e){
            System.err.println("Saving failed: "+e);
        }
        catch(IOException e){
            System.err.println("Saving failed: "+e);
        }
    }

    private BookmarkCollection getCollection(){
        return collection;
    }

    public String getFilename(){
        return filename;
    }

    // Where the bookmarks are to be stored persistently.
    private final String filename;
    private final BookmarkCollection collection;
}
