X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fnet%2Fpterodactylus%2Fjsite%2Fcore%2FProject.java;h=130123609b0f88999cb21bd5625b3b43041e3fee;hb=366dd62299ad3bf0f5d8ead81fd6a1c716851eb8;hp=8a1de1d109a78fff16ed9ddfeb315a8d37463b64;hpb=c785ca4d7b634f79e1f30202915633aa92e4152c;p=jSite2.git diff --git a/src/net/pterodactylus/jsite/core/Project.java b/src/net/pterodactylus/jsite/core/Project.java index 8a1de1d..1301236 100644 --- a/src/net/pterodactylus/jsite/core/Project.java +++ b/src/net/pterodactylus/jsite/core/Project.java @@ -19,19 +19,53 @@ package net.pterodactylus.jsite.core; +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.jsite.core.Node; +import net.pterodactylus.jsite.util.IdGenerator; +import net.pterodactylus.util.beans.AbstractBean; +import net.pterodactylus.util.number.Hex; + /** - * Container for project information. + * 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> - * @version $Id$ */ -public class Project { +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 local path of the project. */ - private String localPath; + /** The description of the project. */ + private String description; /** The public key. */ private String publicKey; @@ -39,12 +73,67 @@ public class Project { /** 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 fileOverrides = new HashMap(); + + /** The default node to insert to. */ + private Node node; + + /** The current root project file. */ + private ProjectFileImpl rootProjectFile; + + /** + * Creates a new project. + */ + public Project() { + id = Hex.toHex(IdGenerator.generateId()); + } + + /** + * Clones the given project. + * + * @param project + */ + Project(Project project) { + this(); + 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 */ - String getName() { + public String getName() { return name; } @@ -54,27 +143,31 @@ public class Project { * @param name * The name of the project */ - void setName(String name) { + public void setName(String name) { + String oldName = this.name; this.name = name; + fireIfPropertyChanged(PROPERTY_NAME, oldName, name); } /** - * Returns the local path of the project. + * Returns the description of the project. * - * @return The local path of the project + * @return The description of the project */ - String getLocalPath() { - return localPath; + public String getDescription() { + return description; } /** - * Sets the local path of the project. + * Sets the description of the project * - * @param localPath - * The local path of the project + * @param description + * The description of the project */ - void setLocalPath(String localPath) { - this.localPath = localPath; + public void setDescription(String description) { + String oldDescription = this.description; + this.description = description; + fireIfPropertyChanged(PROPERTY_DESCRIPTION, oldDescription, description); } /** @@ -82,7 +175,7 @@ public class Project { * * @return The public key of the project */ - String getPublicKey() { + public String getPublicKey() { return publicKey; } @@ -93,7 +186,9 @@ public class Project { * The public key of the project */ void setPublicKey(String publicKey) { + String oldPublicKey = this.publicKey; this.publicKey = publicKey; + fireIfPropertyChanged(PROPERTY_PUBLIC_KEY, oldPublicKey, publicKey); } /** @@ -101,7 +196,7 @@ public class Project { * * @return The private key of the project */ - String getPrivateKey() { + public String getPrivateKey() { return privateKey; } @@ -112,7 +207,415 @@ public class Project { * 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 null 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 null 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 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 null 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 null 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; + } + + /** + * Returns the default node to insert this project to. + * + * @return The node to insert this project to + */ + public Node getNode() { + return node; + } + + /** + * Sets the default node to insert this project to. + * + * @param node + * The node to insert this project to + */ + void setNode(Node node) { + this.node = node; + } + + // + // 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 { + + /** 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 childProjectFiles = new ArrayList(); + + /** + * Creates a new project fie. + * + * @param parentProjectFile + * The parent of the project file, or null 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 + * true if this project file is a directory, + * false otherwise + * @param isHidden + * true if this project file is hidden, + * false 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.ProjectFile#getName() + */ + public String getName() { + return name; + } + + /** + * @see net.pterodactylus.jsite.core.ProjectFile#getParent() + */ + public ProjectFile getParent() { + return parentProjectFile; + } + + /** + * {@inheritDoc} + */ + public long getSize() { + return size; + } + + /** + * @see net.pterodactylus.jsite.core.ProjectFile#getParents() + */ + public List getParents() { + List parentProjectFiles = new ArrayList(); + 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.ProjectFile#isFile() + */ + public boolean isFile() { + return !directory; + } + + /** + * @see net.pterodactylus.jsite.core.ProjectFile#isDirectory() + */ + public boolean isDirectory() { + return directory; + } + + /** + * @see net.pterodactylus.jsite.core.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 null 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.ProjectFile#getFiles() + */ + public List getFiles() { + List projectFiles = new ArrayList(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 + * true if the new file is a directory, + * false otherwise + * @param isHidden + * true if the new file is hidden, + * false 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); + } + } }