add project creation
[jSite2.git] / src / net / pterodactylus / jsite / core / ProjectManager.java
1 /*
2  * jSite2 - ProjectManager.java -
3  * Copyright © 2008 David Roden
4  *
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.
9  *
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.
14  *
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.
18  */
19
20 package net.pterodactylus.jsite.core;
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.Properties;
32
33 import net.pterodactylus.util.io.Closer;
34
35 /**
36  * Manages projects, taking care of persistence, lifetime statistics, and other
37  * things.
38  * 
39  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
40  * @version $Id$
41  */
42 public class ProjectManager {
43
44         /** The directory the projects are stored in. */
45         private final String directory;
46
47         /** The node manager. */
48         private NodeManager nodeManager;
49
50         /** All projects. */
51         private final List<Project> projects = Collections.synchronizedList(new ArrayList<Project>());
52
53         /**
54          * Creates a new project manager that saves and restores its state to/from
55          * the given directory.
56          * 
57          * @param directory
58          *            The directory to save and restore states to/from
59          */
60         public ProjectManager(String directory) {
61                 this.directory = directory;
62         }
63
64         //
65         // ACCESSORS
66         //
67
68         /**
69          * Returns the directory the projects are loaded from and saved to.
70          * 
71          * @return The directory for storing the projects
72          */
73         public String getDirectory() {
74                 return directory;
75         }
76
77         /**
78          * Returns a list of all projects.
79          * 
80          * @return A list of all projects
81          */
82         public List<Project> getProjects() {
83                 return Collections.unmodifiableList(new ArrayList<Project>(projects));
84         }
85
86         /**
87          * Sets the node manager to use.
88          * 
89          * @param nodeManager
90          *            The node manager to use
91          */
92         public void setNodeManager(NodeManager nodeManager) {
93                 this.nodeManager = nodeManager;
94         }
95
96         //
97         // ACTIONS
98         //
99
100         /**
101          * Loads projects and statistics.
102          * 
103          * @throws IOException
104          *             if an I/O error occurs
105          */
106         public void load() throws IOException {
107                 File directoryFile = new File(directory);
108                 File projectFile = new File(directoryFile, "projects.properties");
109                 if (!projectFile.exists() || !projectFile.isFile() || !projectFile.canRead()) {
110                         return;
111                 }
112                 Properties projectProperties = new Properties();
113                 InputStream projectInputStream = null;
114                 try {
115                         projectInputStream = new FileInputStream(projectFile);
116                         projectProperties.load(projectInputStream);
117                 } finally {
118                         Closer.close(projectInputStream);
119                 }
120                 int projectIndex = 0;
121                 while (projectProperties.containsKey("projects." + projectIndex + ".name")) {
122                         String projectPrefix = "projects." + projectIndex;
123                         String projectName = projectProperties.getProperty(projectPrefix + ".name");
124                         String projectDescription = projectProperties.getProperty(projectPrefix + ".description");
125                         String projectPrivateKey = projectProperties.getProperty(projectPrefix + ".privateKey");
126                         String projectPublicKey = projectProperties.getProperty(projectPrefix + ".publicKey");
127                         Project project = new Project();
128                         project.setName(projectName);
129                         project.setDescription(projectDescription);
130                         project.setPrivateKey(projectPrivateKey);
131                         project.setPublicKey(projectPublicKey);
132                         projectIndex++;
133                 }
134         }
135
136         /**
137          * Saves projects and statistics.
138          * 
139          * @throws IOException
140          *             if an I/O error occurs
141          */
142         public void save() throws IOException {
143                 File directoryFile = new File(directory);
144                 if (!directoryFile.exists()) {
145                         if (!directoryFile.mkdirs()) {
146                                 throw new IOException("could not create directory: " + directory);
147                         }
148                 }
149                 Properties projectProperties = new Properties();
150                 int projectIndex = 0;
151                 for (Project project: projects) {
152                         String projectPrefix = "projects." + projectIndex;
153                         projectProperties.setProperty("projects." + projectPrefix + ".name", project.getName());
154                         projectProperties.setProperty("projects." + projectPrefix + ".description", project.getDescription());
155                         projectProperties.setProperty("projects." + projectPrefix + ".privateKey", project.getPrivateKey());
156                         projectProperties.setProperty("projects." + projectPrefix + ".publicKey", project.getPublicKey());
157                         projectIndex++;
158                 }
159                 File projectFile = new File(directoryFile, "projects.properties");
160                 OutputStream projectOutputStream = null;
161                 try {
162                         projectOutputStream = new FileOutputStream(projectFile);
163                         projectProperties.store(projectOutputStream, "jSite projects");
164                 } finally {
165                         Closer.close(projectOutputStream);
166                 }
167         }
168
169         /**
170          * Creates a new project. The returned {@link Project} will contain a newly
171          * generated key pair.
172          * 
173          * @return A newly created project
174          * @throws IOException
175          *             if an I/O error occured communicating with the node
176          * @throws NoNodeException
177          *             if no node is configured
178          */
179         public Project createProject() throws IOException, NoNodeException {
180                 Project project = new Project();
181                 String[] keyPair = nodeManager.generateKeyPair();
182                 project.setPrivateKey(keyPair[0]);
183                 project.setPublicKey(keyPair[1]);
184                 projects.add(project);
185                 try {
186                         save();
187                 } catch (IOException ioe1) {
188                         /* ignore, save() will be called again on quit. */
189                 }
190                 return project;
191         }
192 }