2 * jSite - Project.java - Copyright © 2006–2014 David Roden
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
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
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.
19 package de.todesbaum.jsite.application;
22 import java.util.Collections;
23 import java.util.HashMap;
25 import java.util.Map.Entry;
27 import net.pterodactylus.util.io.MimeTypes;
30 * Container for project information.
32 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
34 public class Project implements Comparable<Project> {
36 /** The name of the project. */
37 protected String name;
39 /** The description of the project. */
40 protected String description;
42 /** The insert URI of the project. */
43 protected String insertURI;
45 /** The request URI of the project. */
46 protected String requestURI;
48 /** The index file of the project. */
49 protected String indexFile;
51 /** The local path of the project. */
52 protected String localPath;
54 /** The remote path of the URI. */
55 protected String path;
57 /** The time of the last insertion. */
58 protected long lastInsertionTime;
60 /** The edition to insert to. */
61 protected int edition;
63 /** Whether to always force inserts. */
64 private boolean alwaysForceInserts;
66 /** Whether to ignore hidden directory. */
67 private boolean ignoreHiddenFiles;
69 /** Options for files. */
70 protected Map<String, FileOption> fileOptions = new HashMap<String, FileOption>();
80 * Creates a new project from an existing one.
83 * The project to clone
85 public Project(Project project) {
87 description = project.description;
88 insertURI = project.insertURI;
89 requestURI = project.requestURI;
91 edition = project.edition;
92 localPath = project.localPath;
93 indexFile = project.indexFile;
94 lastInsertionTime = project.lastInsertionTime;
95 alwaysForceInserts = project.alwaysForceInserts;
96 ignoreHiddenFiles = project.ignoreHiddenFiles;
97 fileOptions = new HashMap<String, FileOption>(project.fileOptions);
101 * Returns the name of the project.
103 * @return The name of the project
105 public String getName() {
110 * Sets the name of the project.
113 * The name of the project
115 public void setName(String name) {
120 * Returns the description of the project.
122 * @return The description of the project
124 public String getDescription() {
129 * Sets the description of the project.
132 * The description of the project
134 public void setDescription(String description) {
135 this.description = description;
139 * Returns the local path of the project.
141 * @return The local path of the project
143 public String getLocalPath() {
148 * Sets the local path of the project.
151 * The local path of the project
153 public void setLocalPath(String localPath) {
154 this.localPath = localPath;
158 * Returns the name of the index file of the project, relative to the
159 * project’s local path.
161 * @return The name of the index file of the project
163 public String getIndexFile() {
168 * Sets the name of the index file of the project, relative to the project’s
172 * The name of the index file of the project
174 public void setIndexFile(String indexFile) {
175 this.indexFile = indexFile;
179 * Returns the time the project was last inserted, in milliseconds since the
182 * @return The time of the last insertion
184 public long getLastInsertionTime() {
185 return lastInsertionTime;
189 * Sets the time the project was last inserted, in milliseconds since the
192 * @param lastInserted
193 * The time of the last insertion
195 public void setLastInsertionTime(long lastInserted) {
196 lastInsertionTime = lastInserted;
200 * Returns the remote path of the project. The remote path is the path that
201 * directly follows the request URI of the project.
203 * @return The remote path of the project
205 public String getPath() {
210 * Sets the remote path of the project. The remote path is the path that
211 * directly follows the request URI of the project.
214 * The remote path of the project
216 public void setPath(String path) {
221 * Returns the insert URI of the project.
223 * @return The insert URI of the project
225 public String getInsertURI() {
230 * Sets the insert URI of the project.
233 * The insert URI of the project
235 public void setInsertURI(String insertURI) {
236 this.insertURI = shortenURI(insertURI);
240 * Returns the request URI of the project.
242 * @return The request URI of the project
244 public String getRequestURI() {
249 * Sets the request URI of the project.
252 * The request URI of the project
254 public void setRequestURI(String requestURI) {
255 this.requestURI = shortenURI(requestURI);
259 * Returns whether files for this project should always be inserted, even
262 * @return {@code true} to always force inserts on this project,
263 * {@code false} otherwise
265 public boolean isAlwaysForceInsert() {
266 return alwaysForceInserts;
270 * Sets whether files for this project should always be inserted, even when
273 * @param alwaysForceInsert
274 * {@code true} to always force inserts on this project,
275 * {@code false} otherwise
277 public void setAlwaysForceInsert(boolean alwaysForceInsert) {
278 this.alwaysForceInserts = alwaysForceInsert;
282 * Returns whether hidden files are ignored, i.e. not inserted.
284 * @return {@code true} if hidden files are not inserted, {@code false}
287 public boolean isIgnoreHiddenFiles() {
288 return ignoreHiddenFiles;
292 * Sets whether hidden files are ignored, i.e. not inserted.
294 * @param ignoreHiddenFiles
295 * {@code true} if hidden files are not inserted, {@code false}
298 public void setIgnoreHiddenFiles(boolean ignoreHiddenFiles) {
299 this.ignoreHiddenFiles = ignoreHiddenFiles;
305 * This method returns the name of the project.
308 public String toString() {
313 * Shortens the given URI by removing scheme and key-type prefixes.
317 * @return The shortened URI
319 private static String shortenURI(String uri) {
320 String shortUri = uri;
321 if (shortUri.startsWith("freenet:")) {
322 shortUri = shortUri.substring("freenet:".length());
324 if (shortUri.startsWith("SSK@")) {
325 shortUri = shortUri.substring("SSK@".length());
327 if (shortUri.startsWith("USK@")) {
328 shortUri = shortUri.substring("USK@".length());
330 if (shortUri.endsWith("/")) {
331 shortUri = shortUri.substring(0, shortUri.length() - 1);
337 * Shortens the name of the given file by removing the local path of the
338 * project and leading file separators.
341 * The file whose name should be shortened
342 * @return The shortened name of the file
344 public String shortenFilename(File file) {
345 String filename = file.getPath();
346 if (filename.startsWith(localPath)) {
347 filename = filename.substring(localPath.length());
348 if (filename.startsWith(File.separator)) {
349 filename = filename.substring(1);
356 * Returns the options for the file with the given name. If the file does
357 * not yet have any options, a new set of default options is created and
361 * The name of the file, relative to the project root
362 * @return The options for the file
364 public FileOption getFileOption(String filename) {
365 FileOption fileOption = fileOptions.get(filename);
366 if (fileOption == null) {
367 fileOption = new FileOption(MimeTypes.getMimeType(filename.substring(filename.lastIndexOf('.') + 1)));
368 fileOptions.put(filename, fileOption);
374 * Sets options for a file.
377 * The filename to set the options for, relative to the project
380 * The options to set for the file, or <code>null</code> to
381 * remove the options for the file
383 public void setFileOption(String filename, FileOption fileOption) {
384 if (fileOption != null) {
385 fileOptions.put(filename, fileOption);
387 fileOptions.remove(filename);
392 * Returns all file options.
394 * @return All file options
396 public Map<String, FileOption> getFileOptions() {
397 return Collections.unmodifiableMap(fileOptions);
401 * Sets all file options.
406 public void setFileOptions(Map<String, FileOption> fileOptions) {
407 this.fileOptions.clear();
408 this.fileOptions.putAll(fileOptions);
414 * Projects are compared by their name only.
417 public int compareTo(Project project) {
418 return name.compareToIgnoreCase(project.name);
422 * Returns the edition of the project.
424 * @return The edition of the project
426 public int getEdition() {
431 * Sets the edition of the project.
436 public void setEdition(int edition) {
437 this.edition = edition;
441 * Constructs the final request URI including the edition number.
444 * The offset for the edition number
445 * @return The final request URI
447 public String getFinalRequestURI(int offset) {
448 return "USK@" + requestURI + "/" + path + "/" + (edition + offset) + "/";
452 * Performs some post-processing on the project after it was inserted
453 * successfully. At the moment it copies the current hashes of all file
454 * options to the last insert hashes, updating the hashes for the next
457 public void onSuccessfulInsert() {
458 for (Entry<String, FileOption> fileOptionEntry : fileOptions.entrySet()) {
459 FileOption fileOption = fileOptionEntry.getValue();
460 if ((fileOption.getCurrentHash() != null) && (fileOption.getCurrentHash().length() > 0) && (!fileOption.getCurrentHash().equals(fileOption.getLastInsertHash()) || fileOption.isForceInsert())) {
461 fileOption.setLastInsertEdition(edition);
462 fileOption.setLastInsertHash(fileOption.getCurrentHash());
463 fileOption.setLastInsertFilename(fileOption.getChangedName().or(fileOptionEntry.getKey()));
465 fileOption.setForceInsert(false);