2 * jSite2 - ProjectManager.java -
3 * Copyright © 2008 David Roden
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 package net.pterodactylus.jsite.project;
22 import java.beans.PropertyChangeEvent;
23 import java.beans.PropertyChangeListener;
25 import java.io.FileInputStream;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.Properties;
34 import java.util.Random;
35 import java.util.logging.Logger;
37 import net.pterodactylus.jsite.core.JSiteException;
38 import net.pterodactylus.jsite.core.NodeManager;
39 import net.pterodactylus.util.io.Closer;
40 import net.pterodactylus.util.logging.Logging;
41 import net.pterodactylus.util.number.Hex;
44 * Manages projects, taking care of persistence, lifetime statistics, and other
47 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
50 public class ProjectManager implements PropertyChangeListener {
53 private static final Logger logger = Logging.getLogger(ProjectManager.class.getName());
55 /** The RNG used to create project IDs. */
56 private static final Random random = new Random();
58 /** The directory the projects are stored in. */
59 private final String directory;
61 /** The node manager. */
62 private NodeManager nodeManager;
65 private final List<Project> projects = Collections.synchronizedList(new ArrayList<Project>());
68 * Creates a new project manager that saves and restores its state to/from
69 * the given directory.
72 * The directory to save and restore states to/from
74 public ProjectManager(String directory) {
75 this.directory = directory;
83 * Returns the directory the projects are loaded from and saved to.
85 * @return The directory for storing the projects
87 public String getDirectory() {
92 * Returns a list of all projects.
94 * @return A list of all projects
96 public List<Project> getProjects() {
97 return Collections.unmodifiableList(new ArrayList<Project>(projects));
101 * Sets the node manager to use.
104 * The node manager to use
106 public void setNodeManager(NodeManager nodeManager) {
107 this.nodeManager = nodeManager;
115 * Loads projects and statistics.
117 * @throws IOException
118 * if an I/O error occurs
120 public void load() throws IOException {
121 File directoryFile = new File(directory);
122 File projectFile = new File(directoryFile, "projects.properties");
123 if (!projectFile.exists() || !projectFile.isFile() || !projectFile.canRead()) {
126 Properties projectProperties = new Properties();
127 InputStream projectInputStream = null;
129 projectInputStream = new FileInputStream(projectFile);
130 projectProperties.load(projectInputStream);
132 Closer.close(projectInputStream);
134 int projectIndex = 0;
135 while (projectProperties.containsKey("projects." + projectIndex + ".name")) {
136 String projectPrefix = "projects." + projectIndex;
137 String projectId = projectProperties.getProperty(projectPrefix + ".id");
138 String projectName = projectProperties.getProperty(projectPrefix + ".name");
139 String projectDescription = projectProperties.getProperty(projectPrefix + ".description");
140 String projectPrivateKey = projectProperties.getProperty(projectPrefix + ".privateKey");
141 String projectPublicKey = projectProperties.getProperty(projectPrefix + ".publicKey");
142 String projectBasePath = projectProperties.getProperty(projectPrefix + ".basePath");
143 Project project = new Project();
144 project.setId(projectId);
145 project.setName(projectName);
146 project.setDescription(projectDescription);
147 project.setPrivateKey(projectPrivateKey);
148 project.setPublicKey(projectPublicKey);
149 project.setBasePath(projectBasePath);
150 project.rescanBasePath();
151 projects.add(project);
152 logger.fine("loaded project “" + project.getName() + "”.");
158 * Saves projects and statistics.
160 * @throws IOException
161 * if an I/O error occurs
163 public void save() throws IOException {
164 File directoryFile = new File(directory);
165 if (!directoryFile.exists()) {
166 if (!directoryFile.mkdirs()) {
167 throw new IOException("could not create directory: " + directory);
170 Properties projectProperties = new Properties();
171 int projectIndex = 0;
172 for (Project project: projects) {
173 String projectPrefix = "projects." + projectIndex;
174 projectProperties.setProperty(projectPrefix + ".id", project.getId());
175 projectProperties.setProperty(projectPrefix + ".name", project.getName());
176 projectProperties.setProperty(projectPrefix + ".description", project.getDescription());
177 projectProperties.setProperty(projectPrefix + ".privateKey", project.getPrivateKey());
178 projectProperties.setProperty(projectPrefix + ".publicKey", project.getPublicKey());
179 projectProperties.setProperty(projectPrefix + ".basePath", project.getBasePath());
182 File projectFile = new File(directoryFile, "projects.properties");
183 OutputStream projectOutputStream = null;
185 projectOutputStream = new FileOutputStream(projectFile);
186 projectProperties.store(projectOutputStream, "jSite projects");
188 Closer.close(projectOutputStream);
193 * Creates a new project. The returned {@link Project} will contain a newly
194 * generated key pair.
196 * @return A newly created project
197 * @throws IOException
198 * if an I/O error occured communicating with the node
199 * @throws JSiteException
200 * if there is a problem with the node
202 public Project createProject() throws IOException, JSiteException {
203 Project project = new Project();
204 String[] keyPair = nodeManager.generateKeyPair();
205 byte[] idBytes = new byte[16];
206 random.nextBytes(idBytes);
207 project.setId(Hex.toHex(idBytes));
209 project.setDescription("");
210 project.setPrivateKey(keyPair[0]);
211 project.setPublicKey(keyPair[1]);
212 projects.add(project);
213 project.addPropertyChangeListener(this);
216 } catch (IOException ioe1) {
223 // INTERFACE PropertyChangeListener
229 public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
232 } catch (IOException ioe1) {