Files
VisualSapfor/src/_VisualDVM/Utils.java
2025-02-12 14:22:11 +03:00

779 lines
32 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package _VisualDVM;
import Common.Passes.PassException;
import Common.Utils.Index;
import Common.Utils.StringTemplate;
import Common.Utils.TextLog;
import Common.Utils.Utils_;
import Common.Visual.UI;
import Common.Visual.Windows.Dialog.VFileChooser_;
import _VisualDVM.GlobalData.Tasks.TaskState;
import _VisualDVM.ProjectData.Files.DBProjectFile;
import _VisualDVM.ProjectData.Project.db_project_info;
import javafx.util.Pair;
import org.apache.commons.io.FileUtils;
import javax.swing.tree.DefaultMutableTreeNode;
import java.io.*;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.security.MessageDigest;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
public class Utils {
public static boolean isLinuxSystemCommand(String text) {
for (String command : Constants.linux_system_commands) {
if (text.equalsIgnoreCase(command)) return true;
}
return false;
}
public static String MFVar(Object o) {
return "$(" + o.toString() + ")";
}
public static String ReadAllText(File file) {
try {
return new String(Files.readAllBytes(file.toPath()));
} catch (Exception e) {
Utils_.MainLog.PrintException(e);
}
return "";
}
public static void CleanDirectory(File dir) {
if (dir.exists() && dir.isDirectory()) {
File[] files = dir.listFiles();
if (files != null) {
for (File f : files) {
try {
Utils_.forceDeleteWithCheck(f);
} catch (Exception e) {
Utils_.MainLog.PrintException(e);
}
}
}
}
}
public static void WriteToFile(File f, String text) throws IOException {
Files.write(
f.toPath(),
text.getBytes(),
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING);
}
// http://java-online.ru/blog-archive.xhtml
public static void getFilesCountR(File dir, Index res) {
for (File f : dir.listFiles()) {
res.Inc();
if (f.isDirectory())
getFilesCountR(f, res);
}
}
public static int getFilesCount(File dir) {
Index res = new Index();
getFilesCountR(dir, res);
return res.getValue();
}
public static File CreateTempResourceFile(String res_name) throws Exception {
URL u = (Utils.class.getResource("/files/" + res_name));
InputStream i = u.openStream();
Path p = Paths.get(Global.TempDirectory.getAbsolutePath(), Utils_.getDateName(res_name));
Files.copy(i, p, StandardCopyOption.REPLACE_EXISTING);
return p.toFile();
}
public static void CreateResourceFile(String res_name, File dst) throws Exception {
URL u = (Utils.class.getResource("/files/" + res_name));
InputStream i = u.openStream();
Files.copy(i, dst.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
//просто дать объект под файл с сгенерированным именем System.out.println
public static File CreateTempFile(String name, String text) throws IOException {
File res = getTempFileName(name);
WriteToFile(res, text);
return res;
}
public static File CreateTempFile(String name, String ext, String text) throws IOException {
File res = getTempFileName(name, ext);
WriteToFile(res, text);
return res;
}
public static File getTempFileName(String name, String ext) {
return Paths.get(System.getProperty("user.dir"), "Temp", Utils_.getDateName(name) + (ext.isEmpty() ? "" : ("." + ext))).toFile();
}
public static File getTempFileName(String name) {
return getTempFileName(name, "");
}
public static boolean isAnchestor(File child, File anchestor) {
return child.getAbsolutePath().startsWith(anchestor.getAbsolutePath() + (Utils_.isWindows() ? "\\" : "/"));
}
//при условии что это точно его предок
public static String getRelativeAddress(File file, File anchestor) {
return file.getAbsolutePath().substring(anchestor.getAbsolutePath().length() + 1);
}
//для переименования/добавления новых файлов.
public static boolean validateFileShortNewName(String name, TextLog Log) {
boolean res = true;
if (name.isEmpty()) {
Log.Writeln_("Имя файла не может быть пустым");
res = false;
}
if (Utils_.ContainsCyrillic(name)) {
Log.Writeln_("Имя файла не может содержать кириллицу");
res = false;
}
if (Utils_.ContainsForbiddenName(name)) {
Log.Writeln_("Имя файла не может содержать запрещённых символов\n" + Utils_.printAllForbiddenCharacters());
res = false;
}
return res;
}
//корень сюда гарантированно не попадает. значит можно запрещать двоеточие.
//идет по всем уровням файлов
public static boolean validateProjectFile(File file, TextLog Log) {
String name = file.getName();
if (Utils_.ContainsCyrillic(name) || Utils_.ContainsForbiddenName(name)) {
Log.Writeln_(file.getAbsolutePath());
return false;
}
return true;
}
//входной параметр всегда папка.
public static void validateProjectFolder_r(File dir, TextLog Log) {
validateProjectFile(dir, Log);
File[] files = dir.listFiles();
if (files != null)
for (File file : files) {
if (file.isDirectory())
validateProjectFolder_r(file, Log);
else validateProjectFile(file, Log);
}
}
public static boolean validateProjectFolder(File dir, TextLog Log) {
TextLog files_list = new TextLog();
String[] filesLines = files_list.text.split("\n");
validateProjectFolder_r(dir, files_list);
if (!files_list.isEmpty())
Log.Writeln_("Имена " + filesLines.length + " файлов/подпапок содержат запрещённые символы " +
Utils_.printAllForbiddenCharacters() +
"или кириллицу");
//нужно проверить корень на наличие хоть одной программы.
return Log.isEmpty();
}
public static void GetVertices(float R, float r, float x0, float y0, int n, float phi) {
boolean inner = false;
for (int i = 0; i < 2 * n; i++) {
float rad = inner ? r : R;
System.out.println("x=" + (x0 + rad * Math.cos(phi + Math.PI * i / n)));
System.out.println("y=" + (y0 + rad * Math.sin(phi + Math.PI * i / n)));
inner = !inner;
}
}
public static String md5Custom(String st) {
MessageDigest messageDigest = null;
byte[] digest = new byte[0];
try {
messageDigest = MessageDigest.getInstance("MD5");
messageDigest.reset();
messageDigest.update(st.getBytes());
digest = messageDigest.digest();
} catch (Exception e) {
// тут можно обработать ошибку
// возникает она если в передаваемый алгоритм в getInstance(,,,) не существует
Utils_.MainLog.PrintException(e);
}
BigInteger bigInt = new BigInteger(1, digest);
String md5Hex = bigInt.toString(16);
while (md5Hex.length() < 32) {
md5Hex = "0" + md5Hex;
}
return md5Hex;
}
public static void renameSubdirs_r(DefaultMutableTreeNode node, File old_anchestor, File new_anchestor) {
if (node.getUserObject() instanceof File) {
File old_file = (File) node.getUserObject();
String relative_name = old_file.getAbsolutePath().substring(old_anchestor.getAbsolutePath().length() + 1);
File new_file = Paths.get(new_anchestor.getAbsolutePath(), relative_name).toFile();
node.setUserObject(new_file);
for (int i = 0; i < node.getChildCount(); ++i) {
renameSubdirs_r((DefaultMutableTreeNode) node.getChildAt(i), old_anchestor, new_anchestor);
}
}
}
public static Socket createClientSocket(InetAddress address, int port, int timeout) throws Exception {
Socket socket = new Socket();
socket.setSoTimeout(timeout);
socket.connect(new InetSocketAddress(address, port), timeout);
return socket;
}
public static void CreateResourceFile(File dst) throws Exception {
URL u = (Utils.class.getResource("/files/" + dst.getName()));
InputStream i = u.openStream();
Files.copy(i, dst.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
public static void getFilesByExtensions_r(File dir, Vector<File> res, String... extensions) {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile()) {
String file_extension = Utils_.getExtension(file);
for (String ext : extensions) {
if (file_extension.equalsIgnoreCase(ext)) {
res.add(file);
}
}
}
if (file.isDirectory())
getFilesByExtensions_r(file, res, extensions);
}
}
}
//----->>
public static void deleteFilesByExtensions(File dir, String... extensions) throws Exception {
Vector<File> res = new Vector<>();
Utils.getFilesByExtensions_r(dir, res, extensions);
for (File src : res)
Utils_.forceDeleteWithCheck(src);
}
//----->>
//--процессы-------------------------------------------------->>>>>
//<editor-fold desc="создание скрипта">
public static Process startScript(File scriptDirectory, File targetDirectory, String name, String scriptText, Map<String, String> envs) throws Exception {
//->
File scriptFile = createScript(scriptDirectory, targetDirectory, name, scriptText);
ProcessBuilder procBuilder = new ProcessBuilder(scriptFile.getAbsolutePath());
procBuilder.directory(scriptDirectory);
procBuilder.redirectErrorStream(true);
if (envs != null) {
for (String envName : envs.keySet()) {
procBuilder.environment().put(envName, envs.get(envName));
}
}
return procBuilder.start();
}
public static Process startScript(File scriptDirectory, File targetDirectory, String name, String scriptText) throws Exception {
return startScript(scriptDirectory, targetDirectory, name, scriptText, null);
}
public static File createScript(File scriptDirectory, File targetDirectory, String name, String scriptText) throws Exception {
//->
File scriptFile = Paths.get(scriptDirectory.getAbsolutePath(), name + (Utils_.isWindows() ? ".bat" : "")).toFile();
FileUtils.write(scriptFile, "cd " + Utils_.DQuotes(targetDirectory.getAbsolutePath()) + "\n" + scriptText);
if (!scriptFile.setExecutable(true)) throw new PassException("Не удалось создать исполняемый файл для скрипта");
return scriptFile;
}
//</editor-fold>
//<editor-fold desc="чтение вывода процесса">
public static String readLine(Process process) throws Exception {
InputStream stdout = process.getInputStream();
InputStreamReader isrStdout = new InputStreamReader(stdout);
BufferedReader brStdout = new BufferedReader(isrStdout);
String line = brStdout.readLine();
return line;
}
public static Vector<String> readAllLines(Process process) throws Exception {
Vector<String> output = new Vector<>();
InputStream stdout = process.getInputStream();
InputStreamReader isrStdout = new InputStreamReader(stdout);
BufferedReader brStdout = new BufferedReader(isrStdout);
String line;
while ((line = brStdout.readLine()) != null) {
output.add(line);
}
return output;
}
public static String readAllOutput(Process process) throws Exception {
return String.join("\n", readAllLines(process));
}
//</editor-fold>
public static String extractHeaderName(String line) {
String tline = line.trim().toLowerCase();
if (tline.startsWith("include")) {
String[] data = tline.split("'");
return data.length > 1 ? data[1] : null;
}
return null;
}
public static String getRelativeName(File dir, File file) {
return
file.getAbsolutePath().startsWith(dir.getAbsolutePath()) ?
file.getAbsolutePath().substring(dir.getAbsolutePath().length() + 1).replace('/', '\\') :
file.getAbsolutePath()
;
}
public static boolean containsLine(Vector<String> list, String line, int max_index) {
int last_index = -1;
for (int i = 0; i < list.size(); ++i)
if (list.get(i).equals(line)) last_index = i;
return (last_index >= max_index);
}
public static String compareTexts(String master, String slave) {
Vector<String> lines = new Vector<>(Arrays.asList(master.split("\n")));
Vector<String> slavelines = new Vector<>(Arrays.asList(slave.split("\n")));
Vector<String> t2 = new Vector<>();
int old_j = 0;
int j = 0;
for (int i = 0; i < lines.size(); ++i) {
if (containsLine(slavelines, lines.get(i), old_j)) {
for (int k = old_j; k < slavelines.size(); ++k) {
j = k;
if (lines.get(i).equals(slavelines.get(k))) {
j++;
t2.add(slavelines.get(k));
break;
} else
t2.add("+ " + slavelines.get(k));
}
old_j = j;
} else {
//строки гарантированно нет.
t2.add("- " + lines.get(i));
}
}
//теперь граничное условие. если первый файл кончился а второй нет, его остаток это добавление.
for (int i = j; i < slavelines.size(); ++i)
t2.add("+ " + slavelines.get(i));
return String.join("\n", t2);
}
public static int getHalfKernels() {
int countCores = 1;
if (Runtime.getRuntime().availableProcessors() > 1)
countCores = Runtime.getRuntime().availableProcessors() / 2;
return countCores;
}
public static int getMaxKernels() {
return Math.max(2, Runtime.getRuntime().availableProcessors());
}
public static int getMatrixProcessors(String matrix) {
if (matrix.trim().isEmpty()) return 1;
String[] data = matrix.split(" ");
int res = 1;
for (String d : data)
res *= Integer.parseInt(d);
return res;
}
public static int getCTestMaxDim(File test) {
int fileMax = 0;
final String prefix = "#pragma dvm array distribute";
int n = 0;
try {
for (String line : FileUtils.readLines(test, Charset.defaultCharset())) {
// #pragma dvm array distribute[block][block], не важно
String packedLine = Utils_.removeCharacters(Utils_.removeRedundantSpaces(line).toLowerCase(), "\n", "\r", "\t");
if (packedLine.startsWith(prefix)) {
packedLine = packedLine.substring(prefix.length());
boolean bracketOpen = false;
int pragmaMax = 0;
String distr = "";
for (int i = packedLine.indexOf('['); i < packedLine.length(); ++i) {
char c = packedLine.charAt(i);
if (bracketOpen) {
if (c == ']') {
bracketOpen = false;
if (distr.equals("block"))
pragmaMax++;
distr = "";
} else {
distr += c;
}
} else {
if (c == '[') {
bracketOpen = true;
} else {
break;
}
}
}
fileMax = Math.max(fileMax, pragmaMax);
}
++n;
}
} catch (Exception ex) {
ex.printStackTrace();
}
return fileMax;
}
public static int getCProjectMaxDim(db_project_info project) {
int res = 0;
for (DBProjectFile file : project.db.files.Data.values()) {
if (file.isActiveProgram())
res = Math.max(res, getCTestMaxDim(file.file));
}
return res;
}
public static boolean isTimeout(long startDate, long maxtime_sec) {
Date now = new Date();
long delta = (now.getTime() - startDate) / 1000;
return (delta > maxtime_sec);
}
//https://translated.turbopages.org/proxy_u/en-ru.ru.596e2df7-62fd38bb-6b4aad49-74722d776562/https/stackoverflow.com/questions/34658054/finding-whole-word-only-in-java-string-search
public static long findInFile(String keyword_in, boolean registerOn, boolean wholeWord, File file) {
if (keyword_in.isEmpty()) return 0;
long res = 0;
try {
String text = FileUtils.readFileToString(file);
String keyword = keyword_in;
//-->>
if (!registerOn) {
text = text.toUpperCase();
keyword = keyword.toUpperCase();
}
String regex = wholeWord ? "\\b" + keyword + "\\b" : keyword;
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) res++;
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
public static void addEmptyLines(Vector<String> lines, int num) {
IntStream.range(0, num).mapToObj(i -> "").forEach(lines::add);
}
protected static boolean isSource(File file) {
if (file.isFile()) {
String extension = Utils_.getExtension(file).toLowerCase();
switch (extension) {
case "f":
case "fdv":
case "for":
case "f77":
case "f90":
// case "fh":
case "c":
case "cdv":
case "cpp":
// case "h":
return true;
}
}
return false;
}
public static boolean containsSource(File folder, boolean question) {
File visualiserData = new File(folder, Constants.data);
if (visualiserData.exists()) {
return true;
} //есть папка с данными, значит его уже открывали, все хорошо.
File[] files = folder.listFiles();
Vector<File> sources = new Vector<>();
if (files != null) {
for (File file : files) {
if (isSource(file)) {
sources.add(file);
}
}
}
if (sources.isEmpty()) {
if (question) return UI.Question("Папка " + Utils_.Brackets(folder.getName()) + "\n" +
"не содержит ни одного файла, распознанного как поддерживаемый код\n" +
"Всё равно открыть её как проект");
else return false;
} else return true;
}
public static void Kill(String PID, boolean force) {
if (!PID.isEmpty()) {
String killCommand =
force ? Utils_.isWindows() ? "taskkill /PID " + Utils_.DQuotes(PID) + " /F /T" : "kill -9 " + Utils_.DQuotes(PID) :
Utils_.isWindows() ? "taskkill /PID " + Utils_.DQuotes(PID) : "kill -2 " + Utils_.DQuotes(PID);
System.out.println(killCommand);
try {
Process killer = Utils.startScript(Global.TempDirectory, Global.TempDirectory, "killer", killCommand);
killer.waitFor();
System.out.println(Utils.readAllOutput(killer));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public static boolean isFunctionName(String name) {
if (name.isEmpty())
return false;
char[] letters = name.toCharArray();
if (!(Utils_.isEnglishLetter(letters[0]) || letters[0] == '_')) {
return false;
}
//---
for (int i = 1; i < letters.length; ++i) {
if (!(Utils_.isEnglishLetter(letters[i]) || letters[i] == '_' || Utils_.isIntegerValue(String.valueOf(letters[i])))) {
return false;
}
}
return true;
}
public static void keepNewFiles(File directory, int count) throws Exception {
if (count > 0) {
File[] old_ = directory.listFiles(pathname -> pathname.isFile());
if (old_ != null) {
Vector<File> old = new Vector<>();
Collections.addAll(old, old_);
old.sort((o1, o2) -> Long.compare(o2.lastModified(), o1.lastModified()));
for (int i = count - 1; i < old.size(); ++i) {
File file = old.get(i);
FileUtils.forceDelete(file);
}
}
}
}
public static boolean isParallelVersionName(String name) {
char[] chars = name.toLowerCase().toCharArray();
if ((chars.length > 1) && (chars[0] == 'p')) {
for (int i = 1; i < chars.length; ++i) {
if (!Character.isDigit(chars[i])) {
return false;
}
}
return true;
}
return false;
}
public static boolean isCrushedLine(String line) {
String l_line = line.toLowerCase();
for (String crushed : Constants.crushed_cases)
if (l_line.contains(crushed))
return true;
return false;
}
public static boolean isCrushed(List<String> output_lines, List<String> errors_lines) {
return output_lines.stream().anyMatch(Utils::isCrushedLine) || errors_lines.stream().anyMatch(Utils::isCrushedLine);
}
public static Pair<TaskState, Integer> analyzeCorrectness(List<String> lines) {
int complete = 0;
int errors = 0;
int total = 0;
int starts = 0;
int ends = 0;
for (String s : lines) {
String line = s.toUpperCase();
if (line.contains("COMPLETE")) {
complete++;
total++;
} else if (line.contains("ERROR")) {
errors++;
total++;
} else if (line.contains("START")) {
starts++;
} else if (line.contains("END")) {
ends++;
}
}
TaskState state = TaskState.Finished;
// if (starts == 0 || ends == 0) {
// state = TaskState.WrongTestFormat;
// } else
if (errors > 0) {
state = TaskState.DoneWithErrors;
} else {
state = TaskState.Done;
}
return new Pair<>(state, (int) ((((double) complete) / total) * 100));
}
public static Pair<TaskState, Integer> analyzePerformance(List<String> lines) {
StringTemplate stringTemplate = new StringTemplate("Verification =", "");
for (String line : lines) {
String param = stringTemplate.check_and_get_param(line);
if (param != null) {
switch (param) {
case "SUCCESSFUL":
return new Pair<>(TaskState.Done, 100);
case "UNSUCCESSFUL":
return new Pair<>(TaskState.DoneWithErrors, 0);
default:
break;
}
}
}
return new Pair<>(TaskState.WrongTestFormat, 0);
}
public static double parseCleanTime(String output) {
double res = 0.0;
StringTemplate template = new StringTemplate("Time in seconds =", "");
String p = template.check_and_get_param(output);
try {
if (p != null) res = Double.parseDouble(p);
} catch (Exception ex) {
Utils_.MainLog.PrintException(ex);
}
return res;
}
public static void RestoreSelectedDirectory(VFileChooser_ directoryChooser) {
String last_dir_home = Global.normalProperties.ProjectsSearchDirectory;
if (!last_dir_home.isEmpty())
directoryChooser.SetCurrentDirectory(last_dir_home);
}
public static void ClearProjectData(File project_home) throws Exception {
Utils.deleteFilesByExtensions(project_home, "dep", "proj");
File project_data = new File(project_home, Constants.data);
if (project_data.exists())
FileUtils.forceDelete(project_data);
}
//--
public static boolean isVersion(File directory) throws Exception {
return new File(directory, Constants.data).exists();
}
public static boolean checkFileCreation(File file) {
for (int i = 1; i <= 10; ++i) {
if (file.exists()) return true;
else Utils_.sleep(1000);
}
return false;
}
public static void createEmptyFile(String name) {
File file = new File(name);
try {
FileUtils.writeStringToFile(file, "");
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static Pair<Vector<String>, Vector<String>> getFortranLines(String text) {
Vector<String> lines = new Vector<>();
Vector<String> visible_lines = new Vector<>();
//1.прочитать весь текст.
char[] chars = text.toCharArray();
//по символам получить строки.
char c = 0; //текущий символ
int i = 0; //индекс текущего символа.
StringBuilder line = new StringBuilder(); //текущая строка
StringBuilder v_line = new StringBuilder(); //текущая строка
while (i < chars.length) {
c = chars[i];
//System.out.print("`"+c+"`");
++i;
switch (c) {
case '\r': //возврат каретки, игнор
break;
case ' ':
case '\t':
if (Global.normalProperties.SpacesOn) line.append(c);
v_line.append(c);
break;
case '\n': //конец строки
if (Global.normalProperties.FortranWrapsOn) {
//оракул. лезем в начало следующей строки
//и анализируем первые 5 символов
boolean hasWrap = false;
int wi;
//------
//с нуля потому что и уже увеличено.
for (int j = 0; (j < 6) && ((wi = i + j) < chars.length); ++j) {
char s = chars[wi];
if ((j == 0) && ((s == 'c') || (s == 'C') || (s == '!'))) {
break;
}
if ((j > 0) && (j < 5) && (s == '!')) {
break;
}
if ((j == 5) && (s != ' ')) {
hasWrap = true;
i = wi + 1;
break;
}
}
//-----
if (hasWrap)
break;
}
//добавление строки в результат.
if ((line.length() > 0) || Global.normalProperties.EmptyLinesOn
// Global.db.settings.get(SettingName.SpacesOn).toBoolean()
) {
lines.add(line.toString());
visible_lines.add(v_line.toString());
}
//сброс
line = new StringBuilder();
v_line = new StringBuilder();
break;
default:
line.append(c);
v_line.append(c);
break;
}
}
if ((i > 0) && (c != '\n')) {
//строка оборвалась на EOF
//добавление строки в результат.
if ((line.length() > 0) || Global.normalProperties.EmptyLinesOn
// && Global.db.settings.get(SettingName.SpacesOn).toBoolean()
) {
lines.add(line.toString());
visible_lines.add(v_line.toString());
}
}
return new Pair<>(lines, visible_lines);
}
public static boolean CompareLines(String line1_raw, String line2_raw) {
String line1 = line1_raw;
String line2 = line2_raw;
if (!Global.normalProperties.RegisterOn) {
line1 = line1.toUpperCase();
line2 = line2.toUpperCase();
}
if (!Global.normalProperties.SpacesOn) {
line1 = Utils_.removeCharacters(line1, " ", "\t");
line2 = Utils_.removeCharacters(line2, " ", "\t");
}
return line1.equals(line2);
}
public static boolean Contains(Vector<String> list, String line, int max_index) {
int last_index = -1;
for (int i = 0; i < list.size(); ++i)
if (CompareLines(list.get(i), line)) last_index = i;
return (last_index >= max_index);
}
public static boolean compareFortranTexts(String text1, String text2) {
Pair<Vector<String>, Vector<String>> p1 = getFortranLines(text1);
Pair<Vector<String>, Vector<String>> p2 = getFortranLines(text2);
Vector<String> lines1 = p1.getKey();
Vector<String> lines2 = p2.getKey();
if (lines1.size() != lines2.size())
return false;
for (int i = 0; i < lines1.size(); ++i) {
if (!CompareLines(lines1.get(i), lines2.get(i)))
return false;
}
return true;
}
//--
private static void get_newest_file_date_r(File dir, Vector<Long> dates) {
Vector<File> files = new Vector(Arrays.asList(dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isFile();
}
})));
if (!files.isEmpty()) {
files.sort(new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
return Long.compare(o1.lastModified(), o2.lastModified());
}
}.reversed());
dates.add(files.firstElement().lastModified());
}
//--
Vector<File> subdirs = new Vector(Arrays.asList(dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory();
}
})));
if (!subdirs.isEmpty()) {
for (File subdir : subdirs)
get_newest_file_date_r(subdir, dates);
}
}
public static long getNewestFileDate(File dir) {
Vector<Long> dates = new Vector<>();
get_newest_file_date_r(dir, dates);
Collections.sort(dates);
if (dates.isEmpty()) {
dates.add(dir.lastModified());
}
return dates.firstElement();
}
}