//////////////////////////////////////////////////////////////////////////////// // 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.apache.commons.io.FileUtils; import com.teotigraphix.caustk.controller.ICaustkController; import com.teotigraphix.caustk.core.CtkDebug; /** * 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) { this.controller = controller; } //------------------------------------------------------------------------- // IProjectManager API //-------------------------------------------------------------------------- @Override public void initialize() { CtkDebug.log("IProjectManager.initialize()"); File applicationRoot = controller.getConfiguration().getApplicationRoot(); projectDirectory = new File(applicationRoot, "projects"); sessionPreferencesFile = new File(applicationRoot, ".settings"); if (!sessionPreferencesFile.exists()) { try { FileUtils.writeStringToFile(sessionPreferencesFile, ""); sessionPreferences = new SessionPreferences(); CtkDebug.log("Created new .settings file: " + sessionPreferencesFile.getAbsolutePath()); saveProjectPreferences(); } catch (IOException e) { e.printStackTrace(); } } else { if (sessionPreferencesFile.exists()) { sessionPreferences = controller.getSerializeService().fromFile( sessionPreferencesFile, SessionPreferences.class); CtkDebug.log("Loaded .settings file: " + sessionPreferencesFile.getAbsolutePath()); } } } @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 { // XXX project manager project.getFile absolute path doubled up CtkDebug.log("IProjectManager.save(): " + project.getStateFile()); sessionPreferences.put("lastProject", project.getDirectory().getPath()); // set modified project.getInfo().setModified(new Date()); //System.out.println(">> SAVE"); controller.getDispatcher().trigger( new OnProjectManagerChange(project, ProjectManagerChangeKind.SAVE)); //System.out.println(">> SAVE_COMPLETE"); controller.getDispatcher().trigger( new OnProjectManagerChange(project, ProjectManagerChangeKind.SAVE_COMPLETE)); finalizeSaveComplete(); } protected void finalizeSaveComplete() throws IOException { //System.out.println(">> SAVE_COMPLETE flushProjectFile()"); CtkDebug.log("IProjectManager; Save Complete, now saving project json file"); String data = controller.getSerializeService().toPrettyString(project); FileUtils.writeStringToFile(project.getStateFile(), data); saveProjectPreferences(); } private void saveProjectPreferences() throws IOException { String data = controller.getSerializeService().toPrettyString(sessionPreferences); FileUtils.writeStringToFile(sessionPreferencesFile, data); } @Override public Project load(File directory) throws IOException { if (directory.getName().contains(".")) throw new IOException("Project is not a directory"); directory = toProjectFile(directory); if (!directory.exists()) throw new IOException("Project file does not exist"); CtkDebug.log("IProjectManager.load():" + directory.getAbsolutePath()); project = controller.getSerializeService().fromFile(new File(directory, ".project"), Project.class); project.open(); controller.getDispatcher().trigger( new OnProjectManagerChange(project, ProjectManagerChangeKind.LOAD)); return project; } @Override public Project create(File file) throws IOException { if (file.getName().contains(".")) throw new IOException("Project is not a directory"); project = new Project(); project.setInitializing(true); // set the project sub directory in the /projects directory project.setDirectory(new File(projectDirectory, file.getName())); project.setInfo(createInfo()); project.open(); CtkDebug.log("IProjectManager.create(): " + project.getDirectory().getAbsolutePath()); controller.getDispatcher().trigger( new OnProjectManagerChange(project, ProjectManagerChangeKind.CREATE)); // create the projects resources directory which is the same name File directory = new File(projectDirectory, project.getName()); FileUtils.forceMkdir(directory); // save the new Project finalizeSaveComplete(); // adding a LOAD event here to keep consistent with all startup. // whether a project is created or loaded on start, mediators will always // get a load event at start. controller.getDispatcher().trigger( new OnProjectManagerChange(project, ProjectManagerChangeKind.LOAD)); project.setInitializing(false); 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()); } }