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