//////////////////////////////////////////////////////////////////////////////// // Copyright 2013 Michael Schmalle - Teoti Graphix, LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License // // Author: Michael Schmalle, Principal Architect // mschmalle at teotigraphix dot com //////////////////////////////////////////////////////////////////////////////// package com.teotigraphix.caustk.project; import java.io.File; import java.io.IOException; import java.util.Date; import org.androidtransfuse.event.EventObserver; import org.apache.commons.io.FileUtils; import com.teotigraphix.caustk.controller.ICaustkController; import com.teotigraphix.caustk.controller.ICaustkController.OnControllerSave; /** * The project manager manages the single project loaded for an application. * <p> * The manager will have a root directory passed to it when it is created. All * project related files are stored within this directory. */ public class ProjectManager implements IProjectManager { private ICaustkController controller; private File projectDirectory; private File sessionPreferencesFile; //---------------------------------- // sessionPreferences //---------------------------------- private SessionPreferences sessionPreferences; @Override public SessionPreferences getSessionPreferences() { return sessionPreferences; } //---------------------------------- // applicationRoot //---------------------------------- /** * The root application directory, all {@link Project}s are stored in the * <code>applicationRoot/projects</code> directory. */ //private File applicationRoot; @Override public File getApplicationRoot() { return controller.getConfiguration().getApplicationRoot(); } @Override public File getDirectory(String path) { File directory = new File(getApplicationRoot(), path); if (!directory.exists()) { directory.mkdirs(); } return directory; } //---------------------------------- // project //---------------------------------- private Project project; @Override public Project getProject() { return project; } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- public ProjectManager(ICaustkController controller, File applicationRoot) { this.controller = controller; initialize(controller.getConfiguration().getApplicationRoot()); controller.getDispatcher().register(OnControllerSave.class, new EventObserver<OnControllerSave>() { @Override public void trigger(OnControllerSave object) { try { save(); } catch (IOException e) { e.printStackTrace(); } } }); controller.getDispatcher().register(OnProjectManagerChange.class, new EventObserver<OnProjectManagerChange>() { @Override public void trigger(OnProjectManagerChange object) { if (object.getKind() == ProjectManagerChangeKind.SAVE_COMPLETE) { try { flushProjectFile(); } catch (IOException e) { e.printStackTrace(); } } } }); } //------------------------------------------------------------------------- // IProjectManager API //-------------------------------------------------------------------------- @Override public void initialize(File applicationRoot) { projectDirectory = new File(applicationRoot, "projects"); sessionPreferencesFile = new File(applicationRoot, ".settings"); if (!sessionPreferencesFile.exists()) { try { sessionPreferencesFile.createNewFile(); sessionPreferences = new SessionPreferences(); saveProjectPreferences(); } catch (IOException e) { e.printStackTrace(); } } else { if (sessionPreferencesFile.exists()) { sessionPreferences = controller.getSerializeService().fromFile( sessionPreferencesFile, SessionPreferences.class); } } } @Override public boolean isProject(File file) { if (file.isAbsolute()) return file.exists(); return toProjectFile(file).exists(); } @Override public void exit() throws IOException { save(); Project oldProject = project; project.close(); project = null; controller.getDispatcher().trigger( new OnProjectManagerChange(oldProject, ProjectManagerChangeKind.EXIT)); } @Override public void save() throws IOException { sessionPreferences.put("lastProject", project.getFile().getPath()); // set modified project.getInfo().setModified(new Date()); controller.getDispatcher().trigger( new OnProjectManagerChange(project, ProjectManagerChangeKind.SAVE)); // all finalize actions like saving the full data to disk happen in a separate sequence // NO clients should be changing the Project state in this event controller.getDispatcher().trigger( new OnProjectManagerChange(project, ProjectManagerChangeKind.SAVE_COMPLETE)); } protected void flushProjectFile() throws IOException { String data = controller.getSerializeService().toString(project); FileUtils.writeStringToFile(project.getFile(), data); saveProjectPreferences(); } private void saveProjectPreferences() throws IOException { String data = controller.getSerializeService().toString(sessionPreferences); FileUtils.writeStringToFile(sessionPreferencesFile, data); } @Override public Project load(File file) throws IOException { file = toProjectFile(file); if (!file.exists()) throw new IOException("Project file does not exist"); project = controller.getSerializeService().fromFile(file, Project.class); project.open(); controller.getDispatcher().trigger( new OnProjectManagerChange(project, ProjectManagerChangeKind.LOAD)); return project; } @Override public Project create(File projectFile) throws IOException { project = new Project(); project.setFile(new File(projectDirectory, projectFile.getPath())); project.setInfo(createInfo()); project.open(); controller.getDispatcher().trigger( new OnProjectManagerChange(project, ProjectManagerChangeKind.CREATE)); return project; } //-------------------------------------------------------------------------- // //-------------------------------------------------------------------------- private ProjectInfo createInfo() { ProjectInfo info = new ProjectInfo(); info.setName("Untitled Project"); info.setAuthor("Untitled Author"); info.setCreated(new Date()); info.setModified(new Date()); info.setDescription("A new project"); return info; } private File toProjectFile(File file) { if (file.isAbsolute()) return file; return new File(projectDirectory, file.getPath()); } }