-/*
- * jSite2 - Project.java -
- * Copyright © 2008 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package net.pterodactylus.jsite.core.project;
-
-import java.beans.PropertyChangeListener;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import net.pterodactylus.util.beans.AbstractBean;
-
-/**
- * Container for project information. A Project is capable of notifying
- * {@link PropertyChangeListener}s if any of the contained properties change.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
-public class Project extends AbstractBean {
-
- /** Name of the “name” property. */
- public static final String PROPERTY_NAME = "name";
-
- /** Name of the “description” property. */
- public static final String PROPERTY_DESCRIPTION = "description";
-
- /** Name of the “public key” property. */
- public static final String PROPERTY_PUBLIC_KEY = "publicKey";
-
- /** Name of the “private key” property. */
- public static final String PROPERTY_PRIVATE_KEY = "privateKey";
-
- /** Name of the “base path” property. */
- public static final String PROPERTY_BASE_PATH = "basePath";
-
- /** Name of the “default file” property. */
- public static final String PROPERTY_DEFAULT_FILE = "defaultFile";
-
- /** Internal ID. */
- private String id;
-
- /** The name of the project. */
- private String name;
-
- /** The description of the project. */
- private String description;
-
- /** The public key. */
- private String publicKey;
-
- /** The private key. */
- private String privateKey;
-
- /** The base path of the project. */
- private String basePath;
-
- /** The default file. */
- private String defaultFile;
-
- /** The overrides. */
- private final Map<String, FileOverride> fileOverrides = new HashMap<String, FileOverride>();
-
- /** The current root project file. */
- private ProjectFileImpl rootProjectFile;
-
- /**
- * Creates a new project.
- */
- public Project() {
- /* do nothing. */
- }
-
- /**
- * Clones the given project.
- *
- * @param project
- */
- Project(Project project) {
- this.name = project.name;
- this.description = project.description;
- this.publicKey = project.publicKey;
- this.privateKey = project.privateKey;
- this.basePath = project.basePath;
- }
-
- /**
- * Returns the internal ID.
- *
- * @return The internal ID
- */
- String getId() {
- return id;
- }
-
- /**
- * Sets the internal ID.
- *
- * @param id
- * The internal ID
- */
- void setId(String id) {
- this.id = id;
- }
-
- /**
- * Returns the name of the project.
- *
- * @return The name of the project
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the name of the project.
- *
- * @param name
- * The name of the project
- */
- public void setName(String name) {
- String oldName = this.name;
- this.name = name;
- fireIfPropertyChanged(PROPERTY_NAME, oldName, name);
- }
-
- /**
- * Returns the description of the project.
- *
- * @return The description of the project
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * Sets the description of the project
- *
- * @param description
- * The description of the project
- */
- public void setDescription(String description) {
- String oldDescription = this.description;
- this.description = description;
- fireIfPropertyChanged(PROPERTY_DESCRIPTION, oldDescription, description);
- }
-
- /**
- * Returns the public key of the project.
- *
- * @return The public key of the project
- */
- public String getPublicKey() {
- return publicKey;
- }
-
- /**
- * Sets the public key of the project.
- *
- * @param publicKey
- * The public key of the project
- */
- void setPublicKey(String publicKey) {
- String oldPublicKey = this.publicKey;
- this.publicKey = publicKey;
- fireIfPropertyChanged(PROPERTY_PUBLIC_KEY, oldPublicKey, publicKey);
- }
-
- /**
- * Returns the private key of the project.
- *
- * @return The private key of the project
- */
- public String getPrivateKey() {
- return privateKey;
- }
-
- /**
- * Sets the private key of the project.
- *
- * @param privateKey
- * The private key of the project
- */
- void setPrivateKey(String privateKey) {
- String oldPrivateKey = this.privateKey;
- this.privateKey = privateKey;
- fireIfPropertyChanged(PROPERTY_PRIVATE_KEY, oldPrivateKey, privateKey);
- }
-
- /**
- * Returns the base path of the project.
- *
- * @return The base path of the project
- */
- public String getBasePath() {
- return basePath;
- }
-
- /**
- * Sets the base path of the project.
- *
- * @param basePath
- * The base path of the project
- */
- public void setBasePath(String basePath) {
- String oldBasePath = this.basePath;
- this.basePath = basePath;
- fireIfPropertyChanged(PROPERTY_BASE_PATH, oldBasePath, basePath);
- }
-
- /**
- * Returns the default file.
- *
- * @return The default file
- */
- public String getDefaultFile() {
- return defaultFile;
- }
-
- /**
- * Sets the default file.
- *
- * @param defaultFile
- * The default file
- */
- public void setDefaultFile(String defaultFile) {
- String oldDefaultFile = this.defaultFile;
- this.defaultFile = defaultFile;
- fireIfPropertyChanged(PROPERTY_DEFAULT_FILE, oldDefaultFile, defaultFile);
- }
-
- /**
- * Adds a file override for the given file.
- *
- * @param projectFile
- * The file
- * @param override
- * The override for the file
- */
- public void addFileOverride(ProjectFile projectFile, FileOverride override) {
- addFileOverride(projectFile.getCompletePath(), override);
- }
-
- /**
- * Adds a file override for the given file.
- *
- * @param filePath
- * The file path
- * @param override
- * The override for the file
- */
- public void addFileOverride(String filePath, FileOverride override) {
- fileOverrides.put(filePath, override);
- }
-
- /**
- * Removes the file override for the given file.
- *
- * @param projectFile
- * The file for which to remove the override
- */
- public void removeFileOverride(ProjectFile projectFile) {
- removeFileOverride(projectFile.getCompletePath());
- }
-
- /**
- * Removes the file override for the given file.
- *
- * @param filePath
- * The file path for which to remove the override
- */
- public void removeFileOverride(String filePath) {
- fileOverrides.remove(filePath);
- }
-
- /**
- * Returns the file override for the given file.
- *
- * @param projectFile
- * The file for which to get the override
- * @return The file override, or <code>null</code> if the given file does
- * not have an override
- */
- public FileOverride getFileOverride(ProjectFile projectFile) {
- return getFileOverride(projectFile.getCompletePath());
- }
-
- /**
- * Returns the file override for the given file.
- *
- * @param filePath
- * The file path for which to get the override
- * @return The file override, or <code>null</code> if the given file does
- * not have an override
- */
- public FileOverride getFileOverride(String filePath) {
- return fileOverrides.get(filePath);
- }
-
- /**
- * Returns the list of {@link FileOverride}s.
- *
- * @return All file overrides
- */
- public Map<String, FileOverride> getFileOverrides() {
- return fileOverrides;
- }
-
- /**
- * Scans the base path for files and returns the {@link ProjectFile} for the
- * base path. From this file it is possible to reach all files in the base
- * path. This method is disk-intensive and may take some time on larger
- * directories!
- *
- * @return The file for the base path, or <code>null</code> if the base
- * path does not denote an existing directory
- */
- public ProjectFile getBaseFile() {
- File basePathFile = new File(basePath);
- if (!basePathFile.exists() || !basePathFile.isDirectory()) {
- return null;
- }
- rootProjectFile = new ProjectFileImpl(null, "", 0, true, false);
- scanDirectory(basePathFile, rootProjectFile);
- return rootProjectFile;
- }
-
- /**
- * Returns the file that is specified by its complete path.
- *
- * @param completePath
- * The complete path of the file
- * @return The project file at the given path, or <code>null</code> if
- * there is no such file
- */
- public ProjectFile getFile(String completePath) {
- if (rootProjectFile == null) {
- getBaseFile();
- }
- if ((rootProjectFile == null) || (completePath.length() == 0)) {
- return rootProjectFile;
- }
- String[] pathParts = completePath.split("\\" + File.separator);
- ProjectFileImpl currentProjectFile = rootProjectFile;
- for (String pathPart : pathParts) {
- currentProjectFile = currentProjectFile.getFile(pathPart);
- if (currentProjectFile == null) {
- return null;
- }
- }
- return currentProjectFile;
- }
-
- //
- // PRIVATE METHODS
- //
-
- /**
- * Scans the given directory and recreates the file and directory structure
- * in the given project file.
- *
- * @param directory
- * The directory to scan
- * @param projectFile
- * The project file in which to recreate the directory and file
- * structure
- */
- private void scanDirectory(File directory, ProjectFileImpl projectFile) {
- if (!directory.isDirectory()) {
- return;
- }
- for (File file : directory.listFiles()) {
- ProjectFileImpl projectFileChild = projectFile.addFile(file.getName(), file.length(), file.isDirectory(), file.isHidden());
- if (file.isDirectory()) {
- scanDirectory(file, projectFileChild);
- }
- }
- projectFile.sort();
- }
-
- /**
- * Implementation of a {@link ProjectFile}.
- *
- * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
- */
- private static class ProjectFileImpl implements ProjectFile, Comparable<ProjectFileImpl> {
-
- /** The parent of this project file. */
- private final ProjectFileImpl parentProjectFile;
-
- /** The name of this project file. */
- private final String name;
-
- /** The size of the file. */
- private final long size;
-
- /** Whether this project file is a directory. */
- private final boolean directory;
-
- /** Whether this file is hidden. */
- private final boolean hidden;
-
- /** This project file’s children. */
- private List<ProjectFileImpl> childProjectFiles = new ArrayList<ProjectFileImpl>();
-
- /**
- * Creates a new project fie.
- *
- * @param parentProjectFile
- * The parent of the project file, or <code>null</code> if
- * the new project file does not have a parent
- * @param name
- * The name of the project file
- * @param size
- * The size of the file
- * @param isDirectory
- * <code>true</code> if this project file is a directory,
- * <code>false</code> otherwise
- * @param isHidden
- * <code>true</code> if this project file is hidden,
- * <code>false</code> otherwise
- */
- ProjectFileImpl(ProjectFileImpl parentProjectFile, String name, long size, boolean isDirectory, boolean isHidden) {
- this.parentProjectFile = parentProjectFile;
- this.name = name;
- this.size = size;
- this.directory = isDirectory;
- this.hidden = isHidden;
- }
-
- //
- // INTERFACE ProjectFile
- //
-
- /**
- * @see net.pterodactylus.jsite.core.project.ProjectFile#getName()
- */
- public String getName() {
- return name;
- }
-
- /**
- * @see net.pterodactylus.jsite.core.project.ProjectFile#getParent()
- */
- public ProjectFile getParent() {
- return parentProjectFile;
- }
-
- /**
- * {@inheritDoc}
- */
- public long getSize() {
- return size;
- }
-
- /**
- * @see net.pterodactylus.jsite.core.project.ProjectFile#getParents()
- */
- public List<ProjectFile> getParents() {
- List<ProjectFile> parentProjectFiles = new ArrayList<ProjectFile>();
- ProjectFileImpl currentProjectFile = this;
- do {
- parentProjectFiles.add(0, currentProjectFile);
- } while ((currentProjectFile = currentProjectFile.parentProjectFile) != null);
- return parentProjectFiles;
- }
-
- /**
- * {@inheritDoc}
- */
- /* TODO - caching? */
- public String getCompletePath() {
- StringBuilder completePath = new StringBuilder();
- ProjectFileImpl currentProjectFile = this;
- while ((currentProjectFile != null) && (currentProjectFile.parentProjectFile != null)) {
- completePath.insert(0, currentProjectFile.getName()).insert(0, File.separatorChar);
- currentProjectFile = currentProjectFile.parentProjectFile;
- }
- return (completePath.length() > 0) ? completePath.substring(1) : "";
- }
-
- /**
- * @see net.pterodactylus.jsite.core.project.ProjectFile#isFile()
- */
- public boolean isFile() {
- return !directory;
- }
-
- /**
- * @see net.pterodactylus.jsite.core.project.ProjectFile#isDirectory()
- */
- public boolean isDirectory() {
- return directory;
- }
-
- /**
- * @see net.pterodactylus.jsite.core.project.ProjectFile#isHidden()
- */
- public boolean isHidden() {
- return hidden;
- }
-
- /**
- * Returns the project file with the given name. The project file has to
- * be a direct child of this project file.
- *
- * @param name
- * The name of the file to get
- * @return The project file, or <code>null</code> if there is no
- * project file by that name
- */
- public ProjectFileImpl getFile(String name) {
- if (!isDirectory()) {
- return null;
- }
- for (ProjectFileImpl projectFile : childProjectFiles) {
- if (projectFile.getName().equals(name)) {
- return projectFile;
- }
- }
- return null;
- }
-
- /**
- * @see net.pterodactylus.jsite.core.project.ProjectFile#getFiles()
- */
- public List<ProjectFile> getFiles() {
- List<ProjectFile> projectFiles = new ArrayList<ProjectFile>(childProjectFiles);
- return projectFiles;
- }
-
- //
- // ACTIONS
- //
-
- /**
- * Adds a new project file as child to this project file.
- *
- * @param name
- * The name of the file
- * @param size
- * The size of the file
- * @param isDirectory
- * <code>true</code> if the new file is a directory,
- * <code>false</code> otherwise
- * @param isHidden
- * <code>true</code> if the new file is hidden,
- * <code>false</code> otherwise
- * @return The created project file
- */
- public ProjectFileImpl addFile(String name, long size, boolean isDirectory, boolean isHidden) {
- ProjectFileImpl newProjectFile = new ProjectFileImpl(this, name, size, isDirectory, isHidden);
- childProjectFiles.add(newProjectFile);
- return newProjectFile;
- }
-
- /**
- * Sorts the children of this file.
- */
- public void sort() {
- Collections.sort(childProjectFiles);
- }
-
- //
- // INTERFACE Comparable
- //
-
- /**
- * {@inheritDoc}
- */
- public int compareTo(ProjectFileImpl otherProjectFileImpl) {
- return name.compareTo(otherProjectFileImpl.name);
- }
-
- }
-
-}