2 * jSite - Project.java - Copyright © 2006–2012 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 de.todesbaum.util.mime.DefaultMIMETypes;
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 ignore hidden directory. */
64 private boolean ignoreHiddenFiles;
66 /** Options for files. */
67 protected Map<String, FileOption> fileOptions = new HashMap<String, FileOption>();
77 * Creates a new project from an existing one.
80 * The project to clone
82 public Project(Project project) {
84 description = project.description;
85 insertURI = project.insertURI;
86 requestURI = project.requestURI;
88 edition = project.edition;
89 localPath = project.localPath;
90 indexFile = project.indexFile;
91 lastInsertionTime = project.lastInsertionTime;
92 ignoreHiddenFiles = project.ignoreHiddenFiles;
93 fileOptions = new HashMap<String, FileOption>(project.fileOptions);
97 * Returns the name of the project.
99 * @return The name of the project
101 public String getName() {
106 * Sets the name of the project.
109 * The name of the project
111 public void setName(String name) {
116 * Returns the description of the project.
118 * @return The description of the project
120 public String getDescription() {
125 * Sets the description of the project.
128 * The description of the project
130 public void setDescription(String description) {
131 this.description = description;
135 * Returns the local path of the project.
137 * @return The local path of the project
139 public String getLocalPath() {
144 * Sets the local path of the project.
147 * The local path of the project
149 public void setLocalPath(String localPath) {
150 this.localPath = localPath;
154 * Returns the name of the index file of the project, relative to the
155 * project’s local path.
157 * @return The name of the index file of the project
159 public String getIndexFile() {
164 * Sets the name of the index file of the project, relative to the project’s
168 * The name of the index file of the project
170 public void setIndexFile(String indexFile) {
171 this.indexFile = indexFile;
175 * Returns the time the project was last inserted, in milliseconds since the
178 * @return The time of the last insertion
180 public long getLastInsertionTime() {
181 return lastInsertionTime;
185 * Sets the time the project was last inserted, in milliseconds since the
188 * @param lastInserted
189 * The time of the last insertion
191 public void setLastInsertionTime(long lastInserted) {
192 lastInsertionTime = lastInserted;
196 * Returns the remote path of the project. The remote path is the path that
197 * directly follows the request URI of the project.
199 * @return The remote path of the project
201 public String getPath() {
206 * Sets the remote path of the project. The remote path is the path that
207 * directly follows the request URI of the project.
210 * The remote path of the project
212 public void setPath(String path) {
217 * Returns the insert URI of the project.
219 * @return The insert URI of the project
221 public String getInsertURI() {
226 * Sets the insert URI of the project.
229 * The insert URI of the project
231 public void setInsertURI(String insertURI) {
232 this.insertURI = shortenURI(insertURI);
236 * Returns the request URI of the project.
238 * @return The request URI of the project
240 public String getRequestURI() {
245 * Sets the request URI of the project.
248 * The request URI of the project
250 public void setRequestURI(String requestURI) {
251 this.requestURI = shortenURI(requestURI);
255 * Returns whether hidden files are ignored, i.e. not inserted.
257 * @return {@code true} if hidden files are not inserted, {@code false}
260 public boolean isIgnoreHiddenFiles() {
261 return ignoreHiddenFiles;
265 * Sets whether hidden files are ignored, i.e. not inserted.
267 * @param ignoreHiddenFiles
268 * {@code true} if hidden files are not inserted, {@code false}
271 public void setIgnoreHiddenFiles(boolean ignoreHiddenFiles) {
272 this.ignoreHiddenFiles = ignoreHiddenFiles;
278 * This method returns the name of the project.
281 public String toString() {
286 * Shortens the given URI by removing scheme and key-type prefixes.
290 * @return The shortened URI
292 private String shortenURI(String uri) {
293 String shortUri = uri;
294 if (shortUri.startsWith("freenet:")) {
295 shortUri = shortUri.substring("freenet:".length());
297 if (shortUri.startsWith("SSK@")) {
298 shortUri = shortUri.substring("SSK@".length());
300 if (shortUri.startsWith("USK@")) {
301 shortUri = shortUri.substring("USK@".length());
303 if (shortUri.endsWith("/")) {
304 shortUri = shortUri.substring(0, shortUri.length() - 1);
310 * Shortens the name of the given file by removing the local path of the
311 * project and leading file separators.
314 * The file whose name should be shortened
315 * @return The shortened name of the file
317 public String shortenFilename(File file) {
318 String filename = file.getPath();
319 if (filename.startsWith(localPath)) {
320 filename = filename.substring(localPath.length());
321 if (filename.startsWith(File.separator)) {
322 filename = filename.substring(1);
329 * Returns the options for the file with the given name. If the file does
330 * not yet have any options, a new set of default options is created and
334 * The name of the file, relative to the project root
335 * @return The options for the file
337 public FileOption getFileOption(String filename) {
338 FileOption fileOption = fileOptions.get(filename);
339 if (fileOption == null) {
340 fileOption = new FileOption(DefaultMIMETypes.guessMIMEType(filename));
341 fileOptions.put(filename, fileOption);
347 * Sets options for a file.
350 * The filename to set the options for, relative to the project
353 * The options to set for the file, or <code>null</code> to
354 * remove the options for the file
356 public void setFileOption(String filename, FileOption fileOption) {
357 if (fileOption != null) {
358 fileOptions.put(filename, fileOption);
360 fileOptions.remove(filename);
365 * Returns all file options.
367 * @return All file options
369 public Map<String, FileOption> getFileOptions() {
370 return Collections.unmodifiableMap(fileOptions);
374 * Sets all file options.
379 public void setFileOptions(Map<String, FileOption> fileOptions) {
380 this.fileOptions.clear();
381 this.fileOptions.putAll(fileOptions);
387 * Projects are compared by their name only.
390 public int compareTo(Project project) {
391 return name.compareToIgnoreCase(project.name);
395 * Returns the edition of the project.
397 * @return The edition of the project
399 public int getEdition() {
404 * Sets the edition of the project.
409 public void setEdition(int edition) {
410 this.edition = edition;
414 * Constructs the final request URI including the edition number.
417 * The offset for the edition number
418 * @return The final request URI
420 public String getFinalRequestURI(int offset) {
421 return "USK@" + requestURI + "/" + path + "/" + (edition + offset) + "/";
425 * Performs some post-processing on the project after it was inserted
426 * successfully. At the moment it copies the current hashes of all file
427 * options to the last insert hashes, updating the hashes for the next
430 public void onSuccessfulInsert() {
431 for (Entry<String, FileOption> fileOptionEntry : fileOptions.entrySet()) {
432 FileOption fileOption = fileOptionEntry.getValue();
433 if ((fileOption.getCurrentHash() != null) && (fileOption.getCurrentHash().length() > 0) && (!fileOption.getCurrentHash().equals(fileOption.getLastInsertHash()) || fileOption.isForceInsert())) {
434 fileOption.setLastInsertEdition(edition);
435 fileOption.setLastInsertHash(fileOption.getCurrentHash());
436 fileOption.setLastInsertFilename(fileOption.hasChangedName() ? fileOption.getChangedName() : fileOptionEntry.getKey());
438 fileOption.setForceInsert(false);