bb722e78f4f46e8dc58f444c6c1cf01b14ccfac7
[jSite.git] / src / de / todesbaum / jsite / application / Project.java
1 /*
2  * jSite - Project.java - Copyright © 2006–2011 David Roden
3  *
4  * This program is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU General Public License as published by the Free Software
6  * Foundation; either version 2 of the License, or (at your option) any later
7  * version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16  * Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18
19 package de.todesbaum.jsite.application;
20
21 import java.io.File;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.Map;
25
26 import de.todesbaum.util.mime.DefaultMIMETypes;
27
28 /**
29  * Container for project information.
30  *
31  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
32  */
33 public class Project implements Comparable<Project> {
34
35         /** The name of the project. */
36         protected String name;
37
38         /** The description of the project. */
39         protected String description;
40
41         /** The insert URI of the project. */
42         protected String insertURI;
43
44         /** The request URI of the project. */
45         protected String requestURI;
46
47         /** The index file of the project. */
48         protected String indexFile;
49
50         /** The local path of the project. */
51         protected String localPath;
52
53         /** The remote path of the URI. */
54         protected String path;
55
56         /** The time of the last insertion. */
57         protected long lastInsertionTime;
58
59         /** The edition to insert to. */
60         protected int edition;
61
62         /** Whether to ignore hidden directory. */
63         private boolean ignoreHiddenFiles;
64
65         /** Options for files. */
66         protected Map<String, FileOption> fileOptions = new HashMap<String, FileOption>();
67
68         /**
69          * Empty constructor.
70          */
71         public Project() {
72                 /* do nothing. */
73         }
74
75         /**
76          * Creates a new project from an existing one.
77          *
78          * @param project
79          *            The project to clone
80          */
81         public Project(Project project) {
82                 name = project.name;
83                 description = project.description;
84                 insertURI = project.insertURI;
85                 requestURI = project.requestURI;
86                 path = project.path;
87                 edition = project.edition;
88                 localPath = project.localPath;
89                 indexFile = project.indexFile;
90                 lastInsertionTime = project.lastInsertionTime;
91                 ignoreHiddenFiles = project.ignoreHiddenFiles;
92                 fileOptions = new HashMap<String, FileOption>(project.fileOptions);
93         }
94
95         /**
96          * Returns the name of the project.
97          *
98          * @return The name of the project
99          */
100         public String getName() {
101                 return name;
102         }
103
104         /**
105          * Sets the name of the project.
106          *
107          * @param name
108          *            The name of the project
109          */
110         public void setName(String name) {
111                 this.name = name;
112         }
113
114         /**
115          * Returns the description of the project.
116          *
117          * @return The description of the project
118          */
119         public String getDescription() {
120                 return description;
121         }
122
123         /**
124          * Sets the description of the project.
125          *
126          * @param description
127          *            The description of the project
128          */
129         public void setDescription(String description) {
130                 this.description = description;
131         }
132
133         /**
134          * Returns the local path of the project.
135          *
136          * @return The local path of the project
137          */
138         public String getLocalPath() {
139                 return localPath;
140         }
141
142         /**
143          * Sets the local path of the project.
144          *
145          * @param localPath
146          *            The local path of the project
147          */
148         public void setLocalPath(String localPath) {
149                 this.localPath = localPath;
150         }
151
152         /**
153          * Returns the name of the index file of the project, relative to the
154          * project’s local path.
155          *
156          * @return The name of the index file of the project
157          */
158         public String getIndexFile() {
159                 return indexFile;
160         }
161
162         /**
163          * Sets the name of the index file of the project, relative to the project’s
164          * local path.
165          *
166          * @param indexFile
167          *            The name of the index file of the project
168          */
169         public void setIndexFile(String indexFile) {
170                 this.indexFile = indexFile;
171         }
172
173         /**
174          * Returns the time the project was last inserted, in milliseconds since the
175          * epoch.
176          *
177          * @return The time of the last insertion
178          */
179         public long getLastInsertionTime() {
180                 return lastInsertionTime;
181         }
182
183         /**
184          * Sets the time the project was last inserted, in milliseconds since the
185          * last epoch.
186          *
187          * @param lastInserted
188          *            The time of the last insertion
189          */
190         public void setLastInsertionTime(long lastInserted) {
191                 lastInsertionTime = lastInserted;
192         }
193
194         /**
195          * Returns the remote path of the project. The remote path is the path that
196          * directly follows the request URI of the project.
197          *
198          * @return The remote path of the project
199          */
200         public String getPath() {
201                 return path;
202         }
203
204         /**
205          * Sets the remote path of the project. The remote path is the path that
206          * directly follows the request URI of the project.
207          *
208          * @param path
209          *            The remote path of the project
210          */
211         public void setPath(String path) {
212                 this.path = path;
213         }
214
215         /**
216          * Returns the insert URI of the project.
217          *
218          * @return The insert URI of the project
219          */
220         public String getInsertURI() {
221                 return insertURI;
222         }
223
224         /**
225          * Sets the insert URI of the project.
226          *
227          * @param insertURI
228          *            The insert URI of the project
229          */
230         public void setInsertURI(String insertURI) {
231                 this.insertURI = shortenURI(insertURI);
232         }
233
234         /**
235          * Returns the request URI of the project.
236          *
237          * @return The request URI of the project
238          */
239         public String getRequestURI() {
240                 return requestURI;
241         }
242
243         /**
244          * Sets the request URI of the project.
245          *
246          * @param requestURI
247          *            The request URI of the project
248          */
249         public void setRequestURI(String requestURI) {
250                 this.requestURI = shortenURI(requestURI);
251         }
252
253         /**
254          * Returns whether hidden files are ignored, i.e. not inserted.
255          *
256          * @return {@code true} if hidden files are not inserted, {@code false}
257          *         otherwise
258          */
259         public boolean isIgnoreHiddenFiles() {
260                 return ignoreHiddenFiles;
261         }
262
263         /**
264          * Sets whether hidden files are ignored, i.e. not inserted.
265          *
266          * @param ignoreHiddenFiles
267          *            {@code true} if hidden files are not inserted, {@code false}
268          *            otherwise
269          */
270         public void setIgnoreHiddenFiles(boolean ignoreHiddenFiles) {
271                 this.ignoreHiddenFiles = ignoreHiddenFiles;
272         }
273
274         /**
275          * {@inheritDoc}
276          * <p>
277          * This method returns the name of the project.
278          */
279         @Override
280         public String toString() {
281                 return name;
282         }
283
284         /**
285          * Shortens the given URI by removing scheme and key-type prefixes.
286          *
287          * @param uri
288          *            The URI to shorten
289          * @return The shortened URI
290          */
291         private String shortenURI(String uri) {
292                 String shortUri = uri;
293                 if (shortUri.startsWith("freenet:")) {
294                         shortUri = shortUri.substring("freenet:".length());
295                 }
296                 if (shortUri.startsWith("SSK@")) {
297                         shortUri = shortUri.substring("SSK@".length());
298                 }
299                 if (shortUri.startsWith("USK@")) {
300                         shortUri = shortUri.substring("USK@".length());
301                 }
302                 if (shortUri.endsWith("/")) {
303                         shortUri = shortUri.substring(0, shortUri.length() - 1);
304                 }
305                 return shortUri;
306         }
307
308         /**
309          * Shortens the name of the given file by removing the local path of the
310          * project and leading file separators.
311          *
312          * @param file
313          *            The file whose name should be shortened
314          * @return The shortened name of the file
315          */
316         public String shortenFilename(File file) {
317                 String filename = file.getPath();
318                 if (filename.startsWith(localPath)) {
319                         filename = filename.substring(localPath.length());
320                         if (filename.startsWith(File.separator)) {
321                                 filename = filename.substring(1);
322                         }
323                 }
324                 return filename;
325         }
326
327         /**
328          * Returns the options for the file with the given name. If the file does
329          * not yet have any options, a new set of default options is created and
330          * returned.
331          *
332          * @param filename
333          *            The name of the file, relative to the project root
334          * @return The options for the file
335          */
336         public FileOption getFileOption(String filename) {
337                 FileOption fileOption = fileOptions.get(filename);
338                 if (fileOption == null) {
339                         fileOption = new FileOption(DefaultMIMETypes.guessMIMEType(filename));
340                         fileOptions.put(filename, fileOption);
341                 }
342                 return fileOption;
343         }
344
345         /**
346          * Sets options for a file.
347          *
348          * @param filename
349          *            The filename to set the options for, relative to the project
350          *            root
351          * @param fileOption
352          *            The options to set for the file, or <code>null</code> to
353          *            remove the options for the file
354          */
355         public void setFileOption(String filename, FileOption fileOption) {
356                 if (fileOption != null) {
357                         fileOptions.put(filename, fileOption);
358                 } else {
359                         fileOptions.remove(filename);
360                 }
361         }
362
363         /**
364          * Returns all file options.
365          *
366          * @return All file options
367          */
368         public Map<String, FileOption> getFileOptions() {
369                 return Collections.unmodifiableMap(fileOptions);
370         }
371
372         /**
373          * Sets all file options.
374          *
375          * @param fileOptions
376          *            The file options
377          */
378         public void setFileOptions(Map<String, FileOption> fileOptions) {
379                 this.fileOptions.clear();
380                 this.fileOptions.putAll(fileOptions);
381         }
382
383         /**
384          * {@inheritDoc}
385          * <p>
386          * Projects are compared by their name only.
387          */
388         public int compareTo(Project project) {
389                 return name.compareToIgnoreCase(project.name);
390         }
391
392         /**
393          * Returns the edition of the project.
394          *
395          * @return The edition of the project
396          */
397         public int getEdition() {
398                 return edition;
399         }
400
401         /**
402          * Sets the edition of the project.
403          *
404          * @param edition
405          *            The edition to set
406          */
407         public void setEdition(int edition) {
408                 this.edition = edition;
409         }
410
411         /**
412          * Constructs the final request URI including the edition number.
413          *
414          * @param offset
415          *            The offset for the edition number
416          * @return The final request URI
417          */
418         public String getFinalRequestURI(int offset) {
419                 return "USK@" + requestURI + "/" + path + "/" + (edition + offset) + "/";
420         }
421
422         /**
423          * Performs some post-processing on the project after it was inserted
424          * successfully. At the moment it copies the current hashes of all file
425          * options to the last insert hashes, updating the hashes for the next
426          * insert.
427          */
428         public void onSuccessfulInsert() {
429                 for (FileOption fileOption : fileOptions.values()) {
430                         if ((fileOption.getCurrentHash() != null) && (fileOption.getCurrentHash().length() > 0) && !fileOption.getCurrentHash().equals(fileOption.getLastInsertHash())) {
431                                 fileOption.setLastInsertEdition(edition);
432                                 fileOption.setLastInsertHash(fileOption.getCurrentHash());
433                         }
434                 }
435         }
436
437 }