package ca.concordia.cssanalyser.app;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import ca.concordia.cssanalyser.io.IOHelper;
/**
* Parses input arguments.
* Methods in this class return default values if necessary.
* @author Davood Mazinanian
*
*/
class ParametersParser {
private static Logger LOGGER = FileLogger.getLogger(ParametersParser.class);
@Option(name="--mode", usage="Mode")
private ProgramMode mode;
@Option(name="--url", usage="Url for analysis")
private String url;
@Option(name="--min-sup", usage="Minimum support count for duplicated declarations")
private int minsup;
@Option(name="--max-declarations", usage="Maximum number of declarations extracted in each mixin")
private int maxDeclarations = -1;
@Option(name="--max-calls", usage="Maximum numbef of times a mixin is called")
private int maxCalls = -1;
@Option(name="--max-parameters", usage="Maximum number of the involved parameters")
private int maxParameters = -1;
@Option(name="--out-folder", usage="Folder for the output stuff")
private String outFolder;
@Option(name="--in-folder", usage="Input folder")
private String inFolder;
@Option(name="--folders-file", usage="File containing the paths to the folders")
private String foldersFile;
@Option(name="--urls-file", usage="File containing the list of URLs for analysis")
private String urlsFile;
@Option(name="--input-file", usage="File containing the list of URLs for analysis")
private String inputFile;
private final CmdLineParser parser;
public ParametersParser(String[] args) {
parser = new CmdLineParser(this);
try {
parser.parseArgument(args);
} catch (CmdLineException e) {
LOGGER.error(e.getMessage());
parser.printUsage(System.out);
}
}
/**
* Replace backslashes with forward slashes in a path, add an ending
* forward slash to the path if necessary.
* @param path
* @return
*/
private static String formatPath(String path) {
String toReturn;
toReturn = path.replace("\\", "/");
if (!toReturn.endsWith("/"))
toReturn = toReturn + "/";
return toReturn;
}
public ProgramMode getProgramMode() {
if (mode == null) {
LOGGER.info("No mode parameters is provided. CRAWL mode is selected by default.");
mode = ProgramMode.CRAWL;
}
return mode;
}
public String getOutputFolderPath() {
if (outFolder == null) {
outFolder = formatPath(System.getProperty("user.dir"));
LOGGER.warn(String.format("No output folder was provided, %s is selected by default.", outFolder));
}
return outFolder;
}
public String getInputFolderPath() {
return inFolder;
}
public String getUrl() {
return url;
}
/**
* Returns minimum support count for FP-Growth.
* The minimum (and default) value is 2.
* @return
*/
public int getFPGrowthMinsup() {
if (minsup < 2) {
minsup = 2;
LOGGER.warn("Invalid number (or nothing) was given for minimum support count (--min-sup), 2 is selected by default.");
}
return minsup;
}
/**
* Returns the file path, provided by user, which includes
* a list of folder path's in which program analyze crawled data.
* @return
*/
public String getListOfFoldersPathsToBeAnayzedFile() {
return foldersFile;
}
public String getListOfURLsToAnalyzeFilePath() {
return urlsFile;
}
public int getMaxDeclarations() {
return maxDeclarations;
}
public int getMaxParameters() {
return maxParameters;
}
public int getMaxCalls() {
return maxCalls;
}
/**
* Returns a list of paths to the URLs,
* which are provided in the url list file using --urlsfile:path/to/file
* @return
*/
public Collection<? extends String> getURLs() {
List<String> urls = new ArrayList<>();
try {
String file = IOHelper.readFileToString(getListOfURLsToAnalyzeFilePath());
String[] lines = file.split("\n|\r|\r\n");
for (String line : lines) {
if (!"".equals(line.trim()) && !line.startsWith("--")) {
if (!"".equals(line.trim()) && !line.startsWith("http://")) {
line = "http://" + line;
}
urls.add(line);
}
}
} catch (IOException ioe) {
LOGGER.error("Error reading file " + getListOfURLsToAnalyzeFilePath());
}
return urls;
}
/**
* Get list of folders from the given file using --fildersfile:path/to/file
* @return
*/
public Collection<? extends String> getFoldersListToBeAnalyzed() {
List<String> folderPaths = new ArrayList<>();
try {
String folderPathsFile = getListOfFoldersPathsToBeAnayzedFile();
String file = IOHelper.readFileToString(folderPathsFile);
String[] lines = file.split("\n|\r|\r\n");
String folderPathsFileParentPath = new File(folderPathsFile).getParentFile().getCanonicalPath();
for (String line : lines) {
if (!"".equals(line.trim())) {
if (line.startsWith("--"))
continue;
String path = formatPath(line);
if (new File(folderPathsFileParentPath + "/" + path).exists())
folderPaths.add(folderPathsFileParentPath + "/" + path);
else if (new File(path).exists())
folderPaths.add(path);
else
LOGGER.warn("\"" + path + "\" is not a valid relative or abolute path.");
}
}
} catch (IOException ioe) {
LOGGER.error("IO Exception in reading file " + getListOfFoldersPathsToBeAnayzedFile());
}
return folderPaths;
}
@Override
public String toString() {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
parser.printUsage(outputStream);
return new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
}
public String getFilePath() {
return inputFile;
}
}