net.sourceforge.javadpkg.plugin.io.impl.FileSystemNodeImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dpkg-maven-plugin Show documentation
Show all versions of dpkg-maven-plugin Show documentation
The plugin for creating Debian Packages during a Maven build process.
The newest version!
/*
* dpkg - Debian Package library and the Debian Package Maven plugin
* (c) Copyright 2016 Gerrit Hohl
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package net.sourceforge.javadpkg.plugin.io.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sourceforge.javadpkg.DebianPackageConstants;
import net.sourceforge.javadpkg.io.FileMode;
import net.sourceforge.javadpkg.io.FileOwner;
import net.sourceforge.javadpkg.io.impl.FileModeImpl;
import net.sourceforge.javadpkg.io.impl.FileOwnerImpl;
import net.sourceforge.javadpkg.plugin.io.FileSystemNode;
import net.sourceforge.javadpkg.plugin.io.FileSystemNodeComparator;
import net.sourceforge.javadpkg.plugin.io.FileSystemNodeVisitResult;
import net.sourceforge.javadpkg.plugin.io.FileSystemNodeVisitor;
import net.sourceforge.javadpkg.plugin.io.Path;
/**
*
* A {@link FileSystemNode} implementation.
*
*
* @param
* The type of the attachment.
* @author Gerrit Hohl ([email protected])
* @version 1.0, 10.05.2016 by Gerrit Hohl
*/
public class FileSystemNodeImpl implements FileSystemNode, DebianPackageConstants {
/** The default owner. */
private static final FileOwnerImpl DEFAULT_OWNER = new FileOwnerImpl(ROOT_GROUP_ID, ROOT_GROUP_NAME,
ROOT_USER_ID, ROOT_USER_NAME);
/** The default mode for a directory. */
private static final FileModeImpl DEFAULT_DIRECTORY_MODE = new FileModeImpl(DIRECTORY_MODE);
/** The parent. */
private FileSystemNode parent;
/** The name. */
private String name;
/** The path of the target of the symbolic link. */
private Path symLinkTarget;
/** The owner. */
private FileOwner owner;
/** The mode. */
private FileMode mode;
/** The attachment (optional). */
private A attachment;
/** The child nodes (if the node represents a directory). */
private Map> children;
/** The flag if the node was created by a dependency. */
private boolean createdByDependency;
/**
*
* Creates a node.
*
*
* @param name
* The name.
* @param symLinkTarget
* The path of the target of the symbolic link (optional).
* @param owner
* The owner.
* @param mode
* The mode.
* @param directory
* The flag if the node represents a directory.
* @param attachment
* The attachment (optional).
* @param createdByDependency
* The flag if the node was created by a dependency.
* @throws IllegalArgumentException
* If any of the non-optional parameters are null
.
*/
private FileSystemNodeImpl(String name, Path symLinkTarget, FileOwner owner, FileMode mode, boolean directory, A attachment,
boolean createdByDependency) {
super();
if (name == null)
throw new IllegalArgumentException("Argument name is null.");
if (owner == null)
throw new IllegalArgumentException("Argument owner is null.");
if (mode == null)
throw new IllegalArgumentException("Argument mode is null.");
this.parent = null;
this.name = name;
this.symLinkTarget = symLinkTarget;
this.owner = owner;
this.mode = mode;
if (directory) {
this.children = new HashMap<>();
} else {
this.children = null;
}
this.attachment = attachment;
this.createdByDependency = createdByDependency;
}
/**
*
* Creates a node representing a directory.
*
*
* The node is marked as created by a dependency.
*
*
* @param name
* The name.
* @throws IllegalArgumentException
* If the name is null
.
*/
public FileSystemNodeImpl(String name) {
this(name, null, DEFAULT_OWNER, DEFAULT_DIRECTORY_MODE, true, null, true);
}
@Override
public FileSystemNode getParent() {
return this.parent;
}
@Override
public FileSystemNode setParent(FileSystemNode parent) {
FileSystemNode previousParent;
// --- Do nothing if this node is already a child node of the new parent ---
if (this.parent == parent)
return this.parent;
// --- Remove node from old parent ---
previousParent = this.parent;
this.parent = null;
if (previousParent != null) {
previousParent.removeChild(this);
}
// --- Add node to new parent ---
if (parent != null) {
this.parent = parent;
this.parent.addChild(this);
}
return previousParent;
}
@Override
public String getName() {
return this.name;
}
@Override
public Path getPath() {
Path path, parentPath;
if (this.parent == null) {
path = new PathImpl();
} else {
parentPath = this.parent.getPath();
path = parentPath.createChild(this.name);
}
return path;
}
@Override
public Path getSymLinkTarget() {
return this.symLinkTarget;
}
@Override
public FileOwner getOwner() {
return this.owner;
}
@Override
public FileMode getMode() {
return this.mode;
}
@Override
public boolean isDirectory() {
return (this.children != null);
}
@Override
public boolean isFile() {
return (this.children == null);
}
@Override
public boolean isSymLink() {
return (this.symLinkTarget != null);
}
@Override
public A getAttachment() {
return this.attachment;
}
@Override
public void setAttachment(A attachment) {
this.attachment = attachment;
}
@Override
public FileSystemNode createChildDirectory(String name, FileOwner owner, FileMode mode, A attachment) {
FileSystemNode childNode;
if (name == null)
throw new IllegalArgumentException("Argument name is null.");
if (owner == null)
throw new IllegalArgumentException("Argument owner is null.");
if (mode == null)
throw new IllegalArgumentException("Argument mode is null.");
if (!this.isDirectory())
throw new IllegalStateException("Can't create directory child node |" + name + "| because node |"
+ this.getPath().getAbsolutePath() + "| is not a directory.");
if (this.getChild(name) != null)
throw new IllegalStateException("Can't create directory child node |" + name
+ "|: A child node with that name already exists in the directory node |" + this.getPath().getAbsolutePath()
+ "|.");
childNode = new FileSystemNodeImpl<>(name, null, owner, mode, true, attachment, false);
this.addChild(childNode);
return childNode;
}
@Override
public FileSystemNode createChildFile(String name, FileOwner owner, FileMode mode, A attachment) {
FileSystemNode childNode;
if (name == null)
throw new IllegalArgumentException("Argument name is null.");
if (owner == null)
throw new IllegalArgumentException("Argument owner is null.");
if (mode == null)
throw new IllegalArgumentException("Argument mode is null.");
if (!this.isDirectory())
throw new IllegalStateException("Can't create file child node |" + name + "| because node |"
+ this.getPath().getAbsolutePath() + "| is not a directory.");
if (this.getChild(name) != null)
throw new IllegalStateException("Can't create file child node |" + name
+ "|: A child node with that name already exists in the directory node |" + this.getPath().getAbsolutePath()
+ "|.");
childNode = new FileSystemNodeImpl<>(name, null, owner, mode, false, attachment, false);
this.addChild(childNode);
return childNode;
}
@Override
public FileSystemNode createChildSymLink(String name, Path target, FileOwner owner, FileMode mode, A attachment) {
FileSystemNode childNode;
if (name == null)
throw new IllegalArgumentException("Argument name is null.");
if (target == null)
throw new IllegalArgumentException("Argument target is null.");
if (owner == null)
throw new IllegalArgumentException("Argument owner is null.");
if (mode == null)
throw new IllegalArgumentException("Argument mode is null.");
if (!this.isDirectory())
throw new IllegalStateException("Can't create file child node |" + name + "| because node |"
+ this.getPath().getAbsolutePath() + "| is not a directory.");
if (this.getChild(name) != null)
throw new IllegalStateException("Can't create file child node |" + name
+ "|: A child node with that name already exists in the directory node |" + this.getPath().getAbsolutePath()
+ "|.");
childNode = new FileSystemNodeImpl<>(name, target, owner, mode, false, attachment, false);
this.addChild(childNode);
return childNode;
}
@Override
public FileSystemNode addChild(FileSystemNode child) {
FileSystemNode previousChild;
if (child == null)
throw new IllegalArgumentException("Argument child is null.");
if (this.children == null)
throw new IllegalStateException("Can't add child |" + child.getName() + "| to path |"
+ this.getPath().getAbsolutePath() + "| because it is not a directory.");
// --- Set the child ---
previousChild = this.children.put(child.getName(), child);
if (previousChild == child) {
previousChild = null;
}
// --- Set the parent ---
if (child.getParent() != this) {
child.setParent(this);
}
return previousChild;
}
@Override
public FileSystemNode getChild(String name) {
if (name == null)
throw new IllegalArgumentException("Argument name is null.");
if (this.children == null)
throw new IllegalStateException("Can't search for child |" + name + "| in path |" + this.getPath().getAbsolutePath()
+ "| because it is not a directory.");
return this.children.get(name);
}
@Override
public FileSystemNode removeChild(String name) {
FileSystemNode child;
if (name == null)
throw new IllegalArgumentException("Argument name is null.");
if (this.children == null)
throw new IllegalStateException("Can't remove child |" + name + "| in path |" + this.getPath().getAbsolutePath()
+ "| because it is not a directory.");
child = this.children.remove(name);
if (child != null) {
child.setParent(null);
}
return child;
}
@Override
public boolean removeChild(FileSystemNode child) {
FileSystemNode node;
if (child == null)
throw new IllegalArgumentException("Argument child is null.");
if (this.children == null)
throw new IllegalStateException("Can't remove child |" + child.getName() + "| in path |"
+ this.getPath().getAbsolutePath() + "| because it is not a directory.");
node = this.children.get(child.getName());
if (node == child) {
this.children.remove(child.getName());
return true;
}
return false;
}
@Override
public List> moveChildrenTo(FileSystemNode node) {
List> children, replacedChildren;
FileSystemNode replacedChild;
if (node == null)
throw new IllegalArgumentException("Argument node is null.");
if (this.children == null)
throw new IllegalStateException("Can't move children from path |" + this.getPath().getAbsolutePath() + "| to path |"
+ node.getPath().getAbsolutePath() + "| because the source path is not a directory.");
if (!node.isDirectory())
throw new IllegalStateException("Can't move children from path |" + this.getPath().getAbsolutePath() + "| to path |"
+ node.getPath().getAbsolutePath() + "| because the target path is not a directory.");
children = new ArrayList<>(this.children.values());
replacedChildren = new ArrayList<>();
for (FileSystemNode child : children) {
this.removeChild(child);
replacedChild = node.addChild(child);
if (replacedChild != null) {
replacedChildren.add(replacedChild);
}
}
return replacedChildren;
}
@Override
public FileSystemNode createDirectories(Path path) {
String name;
FileSystemNode childNode;
Path childPath;
if (path == null)
throw new IllegalArgumentException("Argument path is null.");
if (!this.isDirectory())
throw new IllegalStateException("Can't create directories for path |" + path.getAbsolutePath()
+ "| because this node |" + this.getPath().getAbsolutePath() + "| is not a directory.");
// --- Are we looking for this node? ---
name = path.getFirstElement();
if (name == null)
return this;
// --- Look for the child node for the next part of the path ---
childNode = this.children.get(name);
if (childNode == null) {
// --- If it doesn't exist we create it ---
childNode = new FileSystemNodeImpl<>(name);
this.addChild(childNode);
}
// --- Process the rest of the path ---
childPath = path.getChildPath();
// --- But only if there is a rest ---
if (childPath != null) {
childNode = childNode.createDirectories(childPath);
}
return childNode;
}
@Override
public FileSystemNode getNode(Path path) {
String name;
FileSystemNode childNode;
Path childPath;
if (path == null)
throw new IllegalArgumentException("Argument path is null.");
// --- Are we looking for this node? ---
name = path.getFirstElement();
if (name == null)
return this;
// --- Process the rest of the path ---
if (!this.isDirectory())
throw new IllegalStateException("Can't return node for path |" + path.getAbsolutePath() + "| because this node |"
+ this.getPath().getAbsolutePath() + "| is not a directory.");
childNode = this.children.get(name);
if (childNode != null) {
childPath = path.getChildPath();
if (childPath != null) {
childNode = childNode.getNode(childPath);
}
}
return childNode;
}
@Override
public boolean containsOnlyCreatedByDependency() {
if (this.children == null)
return false;
for (FileSystemNode child : this.children.values()) {
if (!child.isCreatedByDependency())
return false;
else if (!child.containsOnlyCreatedByDependency())
return false;
}
return true;
}
@Override
public boolean isCreatedByDependency() {
return this.createdByDependency;
}
@Override
public FileSystemNodeVisitResult walkNodeTree(FileSystemNodeVisitor visitor) throws IOException {
FileSystemNodeVisitResult result;
if (visitor == null)
throw new IllegalArgumentException("Argument visitor is null.");
if (this.isDirectory()) {
result = visitor.preVisitDirectory(this);
switch (result) {
case CONTINUE:
result = this.walkChildNodeTree(visitor);
if (result == FileSystemNodeVisitResult.TERMINATE)
return result;
break;
case SKIP_SIBLINGS:
case SKIP_SUBTREE:
break;
case TERMINATE:
return result;
default:
}
result = visitor.postVisitDirectory(this);
} else {
result = visitor.visitFile(this);
}
return result;
}
/**
*
* Visits the children of this directory node.
*
*
* @param visitor
* The visitor.
* @return The visit result.
* @throws IOException
* If an I/O error occurs.
*/
private FileSystemNodeVisitResult walkChildNodeTree(FileSystemNodeVisitor visitor) throws IOException {
FileSystemNodeVisitResult result;
List> nodes;
// --- Sort the nodes ---
nodes = new ArrayList<>(this.children.values());
Collections.sort(nodes, new FileSystemNodeComparator());
// --- Visit the nodes ---
for (FileSystemNode node : nodes) {
result = node.walkNodeTree(visitor);
switch (result) {
case CONTINUE:
break;
case SKIP_SIBLINGS:
case TERMINATE:
return result;
case SKIP_SUBTREE:
break;
default:
}
}
return FileSystemNodeVisitResult.CONTINUE;
}
}