+++ /dev/null
-/*
- * jSite2 - ProjectManager.java -
- * Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.jsite.project;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Properties;
-import java.util.Random;
-import java.util.Map.Entry;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import net.pterodactylus.jsite.core.JSiteException;
-import net.pterodactylus.jsite.core.NodeManager;
-import net.pterodactylus.util.io.Closer;
-import net.pterodactylus.util.logging.Logging;
-import net.pterodactylus.util.number.Hex;
-
-/**
- * Manages projects, taking care of persistence, lifetime statistics, and other
- * things.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class ProjectManager implements PropertyChangeListener {
-
- /** Logger. */
- private static final Logger logger = Logging.getLogger(ProjectManager.class.getName());
-
- /** The RNG used to create project IDs. */
- private static final Random random = new Random();
-
- /** The directory the projects are stored in. */
- private final String directory;
-
- /** The node manager. */
- private NodeManager nodeManager;
-
- /** All projects. */
- private final List<Project> projects = Collections.synchronizedList(new ArrayList<Project>());
-
- /**
- * Creates a new project manager that saves and restores its state to/from
- * the given directory.
- *
- * @param directory
- * The directory to save and restore states to/from
- */
- public ProjectManager(String directory) {
- this.directory = directory;
- }
-
- //
- // ACCESSORS
- //
-
- /**
- * Returns the directory the projects are loaded from and saved to.
- *
- * @return The directory for storing the projects
- */
- public String getDirectory() {
- return directory;
- }
-
- /**
- * Returns a list of all projects.
- *
- * @return A list of all projects
- */
- public List<Project> getProjects() {
- return Collections.unmodifiableList(new ArrayList<Project>(projects));
- }
-
- /**
- * Sets the node manager to use.
- *
- * @param nodeManager
- * The node manager to use
- */
- public void setNodeManager(NodeManager nodeManager) {
- this.nodeManager = nodeManager;
- }
-
- //
- // ACTIONS
- //
-
- /**
- * Loads projects and statistics.
- *
- * @throws IOException
- * if an I/O error occurs
- */
- public void load() throws IOException {
- File directoryFile = new File(directory);
- File projectFile = new File(directoryFile, "projects.properties");
- if (!projectFile.exists() || !projectFile.isFile() || !projectFile.canRead()) {
- return;
- }
- Properties projectProperties = new Properties();
- InputStream projectInputStream = null;
- try {
- projectInputStream = new FileInputStream(projectFile);
- projectProperties.load(projectInputStream);
- } finally {
- Closer.close(projectInputStream);
- }
- int projectIndex = 0;
- while (projectProperties.containsKey("projects." + projectIndex + ".name")) {
- String projectPrefix = "projects." + projectIndex;
- String projectId = projectProperties.getProperty(projectPrefix + ".id");
- String projectName = projectProperties.getProperty(projectPrefix + ".name");
- String projectDescription = projectProperties.getProperty(projectPrefix + ".description");
- String projectPrivateKey = projectProperties.getProperty(projectPrefix + ".privateKey");
- String projectPublicKey = projectProperties.getProperty(projectPrefix + ".publicKey");
- String projectBasePath = projectProperties.getProperty(projectPrefix + ".basePath");
- String projectDefaultFile = projectProperties.getProperty(projectPrefix + ".defaultFile");
- Project project = new Project();
- project.setId(projectId);
- project.setName(projectName);
- project.setDescription(projectDescription);
- project.setPrivateKey(projectPrivateKey);
- project.setPublicKey(projectPublicKey);
- project.setBasePath(projectBasePath);
- project.setDefaultFile(projectDefaultFile);
- int overrideIndex = 0;
- while (projectProperties.containsKey(projectPrefix + ".overrides." + overrideIndex + ".override")) {
- String filePath = projectProperties.getProperty(projectPrefix + ".overrides." + overrideIndex + ".filePath");
- FileOverride override = FileOverride.valueOf(projectProperties.getProperty(projectPrefix + ".overrides." + overrideIndex + ".override"));
- project.addFileOverride(filePath, override);
- logger.log(Level.FINEST, "read override: " + filePath + ", " + override);
- overrideIndex++;
- }
- projects.add(project);
- logger.fine("loaded project “" + project.getName() + "”.");
- projectIndex++;
- }
- }
-
- /**
- * Saves projects and statistics.
- *
- * @throws IOException
- * if an I/O error occurs
- */
- public void save() throws IOException {
- File directoryFile = new File(directory);
- if (!directoryFile.exists()) {
- if (!directoryFile.mkdirs()) {
- throw new IOException("could not create directory: " + directory);
- }
- }
- Properties projectProperties = new Properties();
- int projectIndex = 0;
- for (Project project : projects) {
- String projectPrefix = "projects." + projectIndex;
- projectProperties.setProperty(projectPrefix + ".id", project.getId());
- projectProperties.setProperty(projectPrefix + ".name", project.getName());
- projectProperties.setProperty(projectPrefix + ".description", project.getDescription());
- projectProperties.setProperty(projectPrefix + ".privateKey", project.getPrivateKey());
- projectProperties.setProperty(projectPrefix + ".publicKey", project.getPublicKey());
- projectProperties.setProperty(projectPrefix + ".basePath", project.getBasePath());
- projectProperties.setProperty(projectPrefix + ".defaultFile", project.getDefaultFile());
- int overrideIndex = 0;
- for (Entry<String, FileOverride> overrideEntry : project.getFileOverrides().entrySet()) {
- projectProperties.setProperty(projectPrefix + ".overrides." + overrideIndex + ".filePath", overrideEntry.getKey());
- projectProperties.setProperty(projectPrefix + ".overrides." + overrideIndex + ".override", overrideEntry.getValue().toString());
- overrideIndex++;
- }
- projectIndex++;
- }
- File projectFile = new File(directoryFile, "projects.properties");
- OutputStream projectOutputStream = null;
- try {
- projectOutputStream = new FileOutputStream(projectFile);
- projectProperties.store(projectOutputStream, "jSite projects");
- } finally {
- Closer.close(projectOutputStream);
- }
- }
-
- /**
- * Creates a new project. The returned {@link Project} will contain a newly
- * generated key pair.
- *
- * @return A newly created project
- * @throws IOException
- * if an I/O error occured communicating with the node
- * @throws JSiteException
- * if there is a problem with the node
- */
- public Project createProject() throws IOException, JSiteException {
- Project project = new Project();
- String[] keyPair = nodeManager.generateKeyPair();
- project.setId(generateId());
- project.setName("");
- project.setDescription("");
- project.setPrivateKey(keyPair[0]);
- project.setPublicKey(keyPair[1]);
- project.setBasePath("");
- project.setDefaultFile("");
- projects.add(project);
- project.addPropertyChangeListener(this);
- try {
- save();
- } catch (IOException ioe1) {
- /* ignore. */
- }
- return project;
- }
-
- /**
- * Clones the given project and returns the clone. The clone will be
- * identical in all user-exposed fields, except for the project’s
- * {@link Project#getId ID}.
- *
- * @param project
- * The project to clone
- * @return The cloned project
- */
- public Project cloneProject(Project project) {
- Project projectClone = new Project(project);
- projects.add(projectClone);
- projectClone.setId(generateId());
- projectClone.addPropertyChangeListener(this);
- try {
- save();
- } catch (IOException ioe1) {
- /* ignore. */
- }
- return projectClone;
- }
-
- /**
- * Removes the given project.
- *
- * @param project
- * The project to remove
- */
- public void removeProject(Project project) {
- projects.remove(project);
- try {
- save();
- } catch (IOException ioe1) {
- /* ignore. */
- }
- }
-
- //
- // PRIVATE METHODS
- //
-
- /**
- * Generates a new random ID, consisting of 16 random bytes converted to a
- * hexadecimal number.
- *
- * @return The new ID
- */
- private static String generateId() {
- byte[] idBytes = new byte[16];
- random.nextBytes(idBytes);
- return Hex.toHex(idBytes);
- }
-
- //
- // INTERFACE PropertyChangeListener
- //
-
- /**
- * {@inheritDoc}
- */
- public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
- try {
- save();
- } catch (IOException ioe1) {
- /* ignore. */
- }
- }
-
-}