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 for (Entry<String, FileOption> fileOption : fileOptions.entrySet()) {
98 fileOptions.put(fileOption.getKey(), new FileOption(fileOption.getValue()));
103 * Returns the name of the project.
105 * @return The name of the project
107 public String getName() {
112 * Sets the name of the project.
115 * The name of the project
117 public void setName(String name) {
122 * Returns the description of the project.
124 * @return The description of the project
126 public String getDescription() {
131 * Sets the description of the project.
134 * The description of the project
136 public void setDescription(String description) {
137 this.description = description;
141 * Returns the local path of the project.
143 * @return The local path of the project
145 public String getLocalPath() {
150 * Sets the local path of the project.
153 * The local path of the project
155 public void setLocalPath(String localPath) {
156 this.localPath = localPath;
160 * Returns the name of the index file of the project, relative to the
161 * project’s local path.
163 * @return The name of the index file of the project
165 public String getIndexFile() {
170 * Sets the name of the index file of the project, relative to the project’s
174 * The name of the index file of the project
176 public void setIndexFile(String indexFile) {
177 this.indexFile = indexFile;
181 * Returns the time the project was last inserted, in milliseconds since the
184 * @return The time of the last insertion
186 public long getLastInsertionTime() {
187 return lastInsertionTime;
191 * Sets the time the project was last inserted, in milliseconds since the
194 * @param lastInserted
195 * The time of the last insertion
197 public void setLastInsertionTime(long lastInserted) {
198 lastInsertionTime = lastInserted;
202 * Returns the remote path of the project. The remote path is the path that
203 * directly follows the request URI of the project.
205 * @return The remote path of the project
207 public String getPath() {
212 * Sets the remote path of the project. The remote path is the path that
213 * directly follows the request URI of the project.
216 * The remote path of the project
218 public void setPath(String path) {
223 * Returns the insert URI of the project.
225 * @return The insert URI of the project
227 public String getInsertURI() {
232 * Sets the insert URI of the project.
235 * The insert URI of the project
237 public void setInsertURI(String insertURI) {
238 this.insertURI = shortenURI(insertURI);
242 * Returns the request URI of the project.
244 * @return The request URI of the project
246 public String getRequestURI() {
251 * Sets the request URI of the project.
254 * The request URI of the project
256 public void setRequestURI(String requestURI) {
257 this.requestURI = shortenURI(requestURI);
261 * Returns whether files for this project should always be inserted, even
264 * @return {@code true} to always force inserts on this project,
265 * {@code false} otherwise
267 public boolean isAlwaysForceInsert() {
268 return alwaysForceInserts;
272 * Sets whether files for this project should always be inserted, even when
275 * @param alwaysForceInsert
276 * {@code true} to always force inserts on this project,
277 * {@code false} otherwise
279 public void setAlwaysForceInsert(boolean alwaysForceInsert) {
280 this.alwaysForceInserts = alwaysForceInsert;
284 * Returns whether hidden files are ignored, i.e. not inserted.
286 * @return {@code true} if hidden files are not inserted, {@code false}
289 public boolean isIgnoreHiddenFiles() {
290 return ignoreHiddenFiles;
294 * Sets whether hidden files are ignored, i.e. not inserted.
296 * @param ignoreHiddenFiles
297 * {@code true} if hidden files are not inserted, {@code false}
300 public void setIgnoreHiddenFiles(boolean ignoreHiddenFiles) {
301 this.ignoreHiddenFiles = ignoreHiddenFiles;
307 * This method returns the name of the project.
310 public String toString() {
315 * Shortens the given URI by removing scheme and key-type prefixes.
319 * @return The shortened URI
321 private static String shortenURI(String uri) {
322 String shortUri = uri;
323 if (shortUri.startsWith("freenet:")) {
324 shortUri = shortUri.substring("freenet:".length());
326 if (shortUri.startsWith("SSK@")) {
327 shortUri = shortUri.substring("SSK@".length());
329 if (shortUri.startsWith("USK@")) {
330 shortUri = shortUri.substring("USK@".length());
332 if (shortUri.endsWith("/")) {
333 shortUri = shortUri.substring(0, shortUri.length() - 1);
339 * Shortens the name of the given file by removing the local path of the
340 * project and leading file separators.
343 * The file whose name should be shortened
344 * @return The shortened name of the file
346 public String shortenFilename(File file) {
347 String filename = file.getPath();
348 if (filename.startsWith(localPath)) {
349 filename = filename.substring(localPath.length());
350 if (filename.startsWith(File.separator)) {
351 filename = filename.substring(1);
358 * Returns the options for the file with the given name. If the file does
359 * not yet have any options, a new set of default options is created and
363 * The name of the file, relative to the project root
364 * @return The options for the file
366 public FileOption getFileOption(String filename) {
367 FileOption fileOption = fileOptions.get(filename);
368 if (fileOption == null) {
369 fileOption = new FileOption(MimeTypes.getMimeType(filename.substring(filename.lastIndexOf('.') + 1)));
370 fileOptions.put(filename, fileOption);
376 * Sets options for a file.
379 * The filename to set the options for, relative to the project
382 * The options to set for the file, or <code>null</code> to
383 * remove the options for the file
385 public void setFileOption(String filename, FileOption fileOption) {
386 if (fileOption != null) {
387 fileOptions.put(filename, fileOption);
389 fileOptions.remove(filename);
394 * Returns all file options.
396 * @return All file options
398 public Map<String, FileOption> getFileOptions() {
399 return Collections.unmodifiableMap(fileOptions);
403 * Sets all file options.
408 public void setFileOptions(Map<String, FileOption> fileOptions) {
409 this.fileOptions.clear();
410 this.fileOptions.putAll(fileOptions);
416 * Projects are compared by their name only.
419 public int compareTo(Project project) {
420 return name.compareToIgnoreCase(project.name);
424 * Returns the edition of the project.
426 * @return The edition of the project
428 public int getEdition() {
433 * Sets the edition of the project.
438 public void setEdition(int edition) {
439 this.edition = edition;
443 * Constructs the final request URI including the edition number.
446 * The offset for the edition number
447 * @return The final request URI
449 public String getFinalRequestURI(int offset) {
450 return "USK@" + requestURI + "/" + path + "/" + (edition + offset) + "/";
454 * Performs some post-processing on the project after it was inserted
455 * successfully. At the moment it copies the current hashes of all file
456 * options to the last insert hashes, updating the hashes for the next
459 public void onSuccessfulInsert() {
460 for (Entry<String, FileOption> fileOptionEntry : fileOptions.entrySet()) {
461 FileOption fileOption = fileOptionEntry.getValue();
462 if ((fileOption.getCurrentHash() != null) && (fileOption.getCurrentHash().length() > 0) && (!fileOption.getCurrentHash().equals(fileOption.getLastInsertHash()) || fileOption.isForceInsert())) {
463 fileOption.setLastInsertEdition(edition);
464 fileOption.setLastInsertHash(fileOption.getCurrentHash());
465 fileOption.setLastInsertFilename(fileOption.getChangedName().orElse(fileOptionEntry.getKey()));
467 fileOption.setForceInsert(false);