net.sourceforge.javadpkg.plugin.impl.DataEntryNodeTransformer Maven / Gradle / Ivy
Show all versions of dpkg-maven-plugin Show documentation
/*
* 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.impl;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.plugin.logging.Log;
import net.sourceforge.javadpkg.ParseException;
import net.sourceforge.javadpkg.plugin.cfg.DataEntry;
import net.sourceforge.javadpkg.plugin.io.Path;
import net.sourceforge.javadpkg.plugin.io.impl.PathImpl;
import net.sourceforge.javadpkg.plugin.io.impl.WildcardFileFilter;
/**
*
* Transforms {@link DataEntry} objects into {@link DataEntryNode} objects.
*
*
* This class is part of the pre-processing / the parsing of the configuration.
*
*
* @author Gerrit Hohl ([email protected])
* @version 1.0, 19.05.2016 by Gerrit Hohl
* @version 1.0, 23.01.2018 by Gerrit Hohl
*/
public class DataEntryNodeTransformer {
/**
*
* Creates a transformer.
*
*/
public DataEntryNodeTransformer() {
super();
}
/**
*
* Transforms the list of {@link DataEntry} objects into a list of
* {@link DataEntryNode} objects.
*
*
* @param log
* The log.
* @param entries
* The list of {@link DataEntry} objects.
* @return The list of {@link DataEntryNode} objects.
* @throws IllegalArgumentException
* If any of the parameters are null
.
* @throws IOException
* If an I/O error occurs.
* @throws ParseException
* If an error occurs during parsing.
*/
public List transform(Log log, List entries) throws IOException, ParseException {
List nodes;
DataEntryNode node;
String target, symLink, targetName, source, sourceName;
File sourceFile, parentFile;
Path path, parentPath;
List fileEntries;
if (log == null)
throw new IllegalArgumentException("Argument log is null.");
if (entries == null)
throw new IllegalArgumentException("Argument entries is null.");
nodes = new ArrayList<>();
for (DataEntry entry : entries) {
// --- Log the entry ---
this.logDataEntry(log, entry);
// --- Target path ---
target = entry.getTargetPath();
if (this.isEmpty(target))
throw new ParseException("Couldn't add target path: Target not set.");
path = PathImpl.parsePath(target);
// --- Symbolic link ---
symLink = entry.getSymLinkPath();
// --- Source path ---
source = entry.getSourcePath();
// --- Do we have a source? ---
if (!this.isEmpty(source)) {
if (!this.isEmpty(symLink))
throw new ParseException("Couldn't process source path |" + source + "|: A symbolic link |" + symLink
+ "| is also set in the entry.");
sourceFile = new File(source);
sourceName = sourceFile.getName();
// --- Do we have a pattern? ---
if (sourceName.contains("*") || sourceName.contains("?")) {
// --- Get all files and directories matching that pattern ---
parentFile = sourceFile.getParentFile();
if (!parentFile.exists())
throw new IOException("Couldn't process source path |" + source + "|: The directory |"
+ parentFile.getAbsolutePath() + "| does not exist.");
if (!parentFile.isDirectory())
throw new IOException("Couldn't process source path |" + source + "|:The path |"
+ parentFile.getAbsolutePath() + "| is not a directory.");
fileEntries = this.walkTree(parentFile, sourceName, path, "", entry.isRecursive());
}
// --- Otherwise it's a directory or a single file ---
else {
fileEntries = new ArrayList<>();
// --- Do we have a directory and recursion enabled? ---
if (sourceFile.isDirectory() && entry.isRecursive()) {
targetName = path.getLastElement();
parentPath = path.getParentPath();
// --- Add the directory ---
fileEntries.add(new FileEntry(targetName, parentPath, ""));
// --- Add its content ---
fileEntries.addAll(this.walkTree(sourceFile, null, path, targetName, entry.isRecursive()));
} else if (sourceFile.isDirectory())
throw new IOException("Couldn't process source path |" + source + "|: The path |"
+ sourceFile.getAbsolutePath() + "| is a directory and recursion is not enabled.");
else {
if (target.endsWith("/")) {
targetName = sourceName;
parentPath = path;
} else {
targetName = path.getLastElement();
parentPath = path.getParentPath();
}
fileEntries.add(new FileEntry(sourceFile, targetName, parentPath, ""));
}
}
// --- Log the files ---
this.logFileEntries(log, fileEntries, source);
// --- Transform the FileEntry objects into DataEntyNode entries ---
for (FileEntry fileEntry : fileEntries) {
if (fileEntry.isDirectory()) {
node = new DataEntryNode(fileEntry.getName(), fileEntry.getParent(), entry.getGroupId(),
entry.getGroupName(), entry.getUserId(), entry.getUserName(), entry.getMode());
} else {
node = new DataEntryNode(fileEntry.getSource(), fileEntry.getName(), fileEntry.getParent(),
entry.getGroupId(), entry.getGroupName(), entry.getUserId(), entry.getUserName(),
entry.getMode(), entry.isProcess(), entry.getEncoding());
}
nodes.add(node);
}
}
// --- Do we have a symbolic link? ---
else if (!this.isEmpty(symLink)) {
targetName = path.getLastElement();
parentPath = path.getParentPath();
// --- Log the symbolic link ---
this.logSymLink(log);
node = new DataEntryNode(targetName, parentPath, symLink, entry.getGroupId(), entry.getGroupName(),
entry.getUserId(), entry.getUserName(), entry.getMode());
nodes.add(node);
}
// --- Otherwise we have a directory ---
else {
targetName = path.getLastElement();
parentPath = path.getParentPath();
// --- Log the directory ---
this.logDirectory(log);
node = new DataEntryNode(targetName, parentPath, entry.getGroupId(), entry.getGroupName(), entry.getUserId(),
entry.getUserName(), entry.getMode());
nodes.add(node);
}
}
return nodes;
}
/**
*
* Returns the flag if the specified value is empty.
*
*
* A {@link String} object is empty if it is null
or
* {@link String#isEmpty()} returns true
.
*
*
* Objects of other classes are empty if they are null
.
*
*
* @param value
* The value.
* @return The flag: true
, if the specified value is empty,
* false
otherwise.
*/
private boolean isEmpty(Object value) {
if (value == null)
return true;
if (value instanceof String)
return ((String) value).isEmpty();
return false;
}
/**
*
* Logs a data entry.
*
*
* @param log
* The log.
* @param entry
* The entry.
*/
private void logDataEntry(Log log, DataEntry entry) {
if (!log.isInfoEnabled())
return;
log.info("Target path : " + entry.getTargetPath());
if (!this.isEmpty(entry.getSourcePath())) {
log.info(" Source path : " + entry.getSourcePath());
}
if (!this.isEmpty(entry.getSymLinkPath())) {
log.info(" SymLink path : " + entry.getSymLinkPath());
}
if (!this.isEmpty(entry.getGroupId())) {
log.info(" Group ID : " + entry.getGroupId().longValue());
}
if (!this.isEmpty(entry.getGroupName())) {
log.info(" Group name : " + entry.getGroupName());
}
if (!this.isEmpty(entry.getUserId())) {
log.info(" User ID : " + entry.getUserId().longValue());
}
if (!this.isEmpty(entry.getUserName())) {
log.info(" User name : " + entry.getUserName());
}
if (!this.isEmpty(entry.getMode())) {
log.info(" Mode : 0" + Integer.toOctalString(entry.getMode().intValue()) + " (Decimal: "
+ entry.getMode().intValue() + ")");
}
log.info(" Recursive : " + entry.isRecursive());
log.info(" Process : " + entry.isProcess());
if (!this.isEmpty(entry.getUserName())) {
log.info(" Encoding : " + entry.getEncoding());
}
}
/**
*
* Logs the file entries.
*
*
* @param log
* The log.
* @param files
* The file entries.
* @param pattern
* The pattern.
*/
private void logFileEntries(Log log, List files, String pattern) {
String name, relativePath;
if (!log.isInfoEnabled())
return;
if (files.isEmpty()) {
log.info(" File(s) for pattern |" + pattern + "|: No files found.");
} else {
log.info(" File(s) for pattern |" + pattern + "|:");
for (FileEntry file : files) {
name = file.getName();
relativePath = file.getRelativePath();
if (!this.isEmpty(relativePath)) {
name = relativePath + "/" + name;
}
if (file.isDirectory()) {
log.info(" " + name);
} else {
log.info(" " + name + " -> " + file.getSource());
}
}
}
}
/**
*
* Logs a symbolic link.
*
*
* @param log
* The log.
*/
private void logSymLink(Log log) {
if (!log.isInfoEnabled())
return;
log.info(" Symbolic link.");
}
/**
*
* Logs a directory.
*
*
* @param log
* The log.
*/
private void logDirectory(Log log) {
if (!log.isInfoEnabled())
return;
log.info(" Directory.");
}
/**
*
* Walks a file system tree starting with the content of the specified
* folder.
*
*
* For every matching file and directory a {@link FileEntry} is created and
* added to the result.
*
*
* The folder itself is not included in the result.
*
*
* @param folder
* The folder.
* @param pattern
* The pattern (optional).
* @param path
* The path of the folder in the target.
* @param relativePath
* The relative path.
* @param recursive
* The flag if the tree should be walked recursively.
* @return The result.
* @throws IOException
* If the content of a folder can't be read.
*/
private List walkTree(File folder, String pattern, Path path, String relativePath, boolean recursive)
throws IOException {
List entries;
File[] files;
FileFilter filter;
String name;
Path childPath;
FileEntry entry;
entries = new ArrayList<>();
// --- Get files ---
if ((pattern == null) || pattern.isEmpty()) {
files = folder.listFiles();
} else {
filter = new WildcardFileFilter(pattern, recursive);
files = folder.listFiles(filter);
}
if (files == null)
throw new IOException("Couldn't read content of directory |" + folder.getAbsolutePath() + "|.");
// --- Process files ---
for (File file : files) {
name = file.getName();
if (file.isDirectory()) {
if (recursive) {
entry = new FileEntry(name, path, relativePath);
entries.add(entry);
childPath = path.createChild(name);
entries.addAll(this.walkTree(file, pattern, childPath, relativePath + "/" + name, recursive));
}
} else {
entry = new FileEntry(file, name, path, relativePath);
entries.add(entry);
}
}
return entries;
}
/* **********************************************************************
* **********************************************************************
* **********************************************************************
* **********************************************************************
* **********************************************************************
*/
/**
*
* An entry for a file.
*
*
* These entries are created when a directory is processed recursively and /
* or a pattern for the source is defined.
*
*
* @author Gerrit Hohl ([email protected])
* @version 1.0, 19.05.2016 by Gerrit Hohl
*/
private class FileEntry {
/** The source (if the file is a regular file). */
private File source;
/** The name in the target. */
private String name;
/** The path of the parent in the target. */
private Path parent;
/** The relative path. */
private String relativePath;
/**
*
* Creates an entry for a regular file.
*
*
* @param source
* The source.
* @param name
* The name in the target.
* @param parent
* The path of the parent in the target.
* @param relativePath
* The relative path.
*/
public FileEntry(File source, String name, Path parent, String relativePath) {
super();
this.source = source;
this.name = name;
this.parent = parent;
this.relativePath = relativePath;
}
/**
*
* Creates an entry for a directory.
*
*
* @param name
* The name in the target.
* @param parent
* The path of the parent in the target.
* @param relativePath
* The relative path.
*/
public FileEntry(String name, Path parent, String relativePath) {
super();
this.source = null;
this.name = name;
this.parent = parent;
this.relativePath = relativePath;
}
/**
*
* Returns the flag if this is an entry for a directory.
*
*
* @return The flag: true
, if this is an entry for a
* directory, false
otherwise.
*/
public boolean isDirectory() {
return (this.source == null);
}
/**
*
* Returns the source.
*
*
* @return The source if the file is a regular file, null
* otherwise.
*/
public File getSource() {
return this.source;
}
/**
*
* Returns the name in the target.
*
*
* @return The name.
*/
public String getName() {
return this.name;
}
/**
*
* Returns the path of the parent in the target.
*
*
* @return The path.
*/
public Path getParent() {
return this.parent;
}
/**
*
* Returns the relative path.
*
*
* @return The relative path.
*/
public String getRelativePath() {
return this.relativePath;
}
}
}