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