Sorting an array of filenames containing strings with numbers - java

For my project I need to download a zip file from an FTP server, which releases a new zip about 13 times a year. I need to download the latest file following the server's naming convention:
Prefix + release number (one or two digits) + year (two digits) + suffix + ".zip"
for instance:
ALFP1016F.zip
The prefix will always be the same (ALFP) and the suffix either F or P (stands for "full" or "partial"; I need only the files ending with suffix F). On top of that, there are several other files in the directory I need to ignore because they have different prefixes. Then, I need to get the most recent file in the array following this priority order:
Most recent year. Of course '99 should not be seen as the most recent year.
Most recent release number
For instance, if I have this listing of filenames (full server directory):
1stpage712.pdf
1stpage914.pdf
ALFP1015F.zip
ALFP1015P.zip
ALFP716F.zip
ALFP716P.zip
FSFP816F.zip
FSFP816P.zip
My expected output would be
ALFP716F.zip because 16 is the most recent year, and 7 the most recent release number from that year
.
Here's what I've done so far:
//necessary imports
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
//initialize FTP client
ftpClient = new FTPClient();
try {
//connect to server
ftpClient.connect(server, port);
ftpClient.login(username, password);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//list all names from server
String[] filenames = ftpClient.listNames();
//return expected file name
String expectedFileName = returnMostRecent(filenames);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
System.out.println("Disconnected from server");
}
} catch (IOException ex) { ex.printStackTrace(); }
}
I have done a miserable attempt at writing the returnMostRecent(String[]) method, but ended up with an unintelligible mess not worth being posted here.
How can I sort this array and effectively return the most recent file following my priority order?

If you use Java8 you can do:
String file = Arrays.stream(filenames)
.filter(s -> s.startsWith("ALFP") && s.endsWith("F.zip"))
.max(getReleaseComparator())
.orElse(null);
where release comparator is based on extracting numbers from file name and comparing them

I haven't tested this but I think it should work.
private String returnMostRecent(String[] fileNames) {
String file = null;
double version = -1;
for(String name : listNames)
{
// skip files that don't match
if (!name.matches("ALFP[0-9]*F.zip"))
continue;
// get digits only
String digits = name.replaceAll("\\D+","");
// format digits to <year>.<version>
String vstr = digits.substring(digits.length-2,digits.length()) + ".";
if (digits.length() < 4)
vstr += "0";
vstr = digits.substring(0, digits.length()-2);
double v = Double.parseDouble(vstr);
if (v > version)
{
version = v;
file = name;
}
}
return file;
}

I will suggest this approach:
final String[] filesArr = { "1stpage712.txt", "1stpage712.pdf", "1stpage914.pdf", "ALFP1015F.zip", "ALFP1015P.zip", "ALFP716F.zip",
"ALFP716P.zip", "FSFP816F.zip", "FSFP816P.zip" };
// turn the array into a list.
final List<String> filesList = new ArrayList<String>();
// add to the list only the good candidates
for (int i = 0; i < filesArr.length; i++) {
if (filesArr[i].matches("ALFP\\d+F.zip")) {
System.out.println("candidate");
filesList.add(filesArr[i]);
}
}
System.out.println(filesList);
Collections.sort(filesList, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
final SimpleDateFormat df = new SimpleDateFormat("mmyy");
// get the date of the file
final String dat1 = o1.substring(o1.indexOf("ALFP"), o1.indexOf("ALFP") + 3);
final String dat2 = o2.substring(o2.indexOf("ALFP"), o2.indexOf("ALFP") + 3);
Date date1;
Date date2;
try {
date1 = df.parse(dat1);
date2 = df.parse(dat2);
return date1.compareTo(date2);
} catch (final ParseException e) {
System.out.println("Error parsing date..");
return 0;
}
}
});
// since the sort is made by date chronologically, the 1st element is the oldest and the last element is
// the newest
System.out.println("The file is: " + filesList.get(filesList.size() - 1));
}

I will suggest this Solution :
private static String returnMostRecent(String[] fileNames)
{
int lastTwoDigits = Calendar.getInstance().get(Calendar.YEAR) % 100;
int fullFileRel = 0;
int partialFileRel = 0;
for(String myStr : fileNames)
{
if(myStr.startsWith("ALFP"))
{
System.out.println(myStr);
if(myStr.endsWith(""+lastTwoDigits+"F.zip"))
{
String temp = myStr.substring(4,myStr.length()-7);
System.out.println("temp : "+temp);
int releaseNum = Integer.parseInt(temp);
System.out.println("releaseNum : "+releaseNum);
if(releaseNum > fullFileRel)
fullFileRel = releaseNum;
}
if(myStr.endsWith(""+lastTwoDigits+"P.zip"))
{
String temp = myStr.substring(4,myStr.length()-7);
System.out.println("temp : "+temp);
int releaseNum = Integer.parseInt(temp);
System.out.println("releaseNum : "+releaseNum);
if(releaseNum > fullFileRel)
partialFileRel = releaseNum;
}
}
}
System.out.println("full Rel :"+fullFileRel);
System.out.println("partial Rel :"+partialFileRel);
if(fullFileRel > partialFileRel)
return "ALFP"+fullFileRel+""+lastTwoDigits+"F.zip";
else
return "ALFP"+partialFileRel+""+lastTwoDigits+"P.zip";
}

You can use regex and do something like this to parse out the year and version:
public static void main(String[] args)
{
int year = -1;
int version = -1;
String test = "ALFP716F.zip";
if(test.matches("ALFP\\d+F.zip"))
{
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(test);
matcher.find();
String tempString = matcher.group(0);
year = Integer.parseInt(tempString.substring((tempString.length() - 2)));
version = Integer.parseInt(tempString.substring(0, (tempString.length() - 2)));
}
System.out.println("Year: " + year + " Version: " + version);
}

Here is Java 1.5 compatible solution, AlphaNumComparator

Related

Is there a way to collect data in multiple excel files?

there are 12 excel files that contain different products sales data, I try to sum up each month and entire year's sales using java but I can't add up sales for the whole year. Is there a way to do that? Thanks for your help.
public class Main {
public static void listOfSales(String fileName,String month){
List<PriceList> list = readsListFroExcel(fileName);
int sumOfInYearSale = 0;
int sumOfInOnlineSale =0;
int sumOfTotalMonthlySale = 0;
for (PriceList x : list){
sumOfInYearSale = sumOfInYearSale + x.getTotalPhysicalSale();
sumOfInOnlineSale = sumOfInYearSale + x.getTotalOnlineSale();
}
System.out.println(month +" Physical Sales : "+sumOfInYearSale);
System.out.println(month+ " Online Sales :" +sumOfInOnlineSale);
}
private static List<PriceList> readsListFroExcel(String fileName) {
List<PriceList> list = new ArrayList<>();
Path pathTofile = Paths.get(fileName);
try (BufferedReader br = Files.newBufferedReader(pathTofile)){
String headerLine = br.readLine();
String line = br.readLine();
while (line!=null){
String[] attributes = line.split(",");
PriceList listOfPrice = createList(attributes);
list.add(listOfPrice);
line = br.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
}

How to compare two set then filter to new set with combination string?

I'm build some short code for compare 2 hashset.
SET 1 = noRek : [1234567892, 1234567891, 1234567890]
SET 2 = Source : [1234567890U0113, 1234567894B0111, 1234567890U0112,
1234567891B0111, 1234567890U0115, 1234567890U0114, 1234567892B0113,
1234567893B0111, 1234567890U0111, 1234567890B0111, 1234567892B0112,
1234567892B0111]
public class diff {
public static void main(String args[]) {
String filename = "C:\\abc.txt";
String filename2 = "C:\\xyz.txt";
HashSet<String> al = new HashSet<String>();
HashSet<String> al1 = new HashSet<String>();
HashSet<String> source = new HashSet<String>();
HashSet<String> noRek = new HashSet<String>();
HashSet<String> diff1 = new HashSet<String>();
HashSet<String> diff2 = new HashSet<String>();
String str = null;
String str2 = null;
Integer digitRek = 10;
Integer digitTransaksi = 15;
//GET REKDATA FROM TARGET
try {
String message = new Scanner(new File(filename2)).useDelimiter("\\Z").next();
for (int i = 0; i < message.length(); i += digitRek) {
noRek.add(message.substring(i, Math.min(i + digitRek, message.length())));
}
System.out.println("noRek : " + noRek);
} catch (Exception e) {
e.printStackTrace();
}
try {
String message2 = new Scanner(new File(filename)).useDelimiter("\\Z").next();
for (int i = 0; i < message2.length(); i += digitTransaksi) {
source.add(message2.substring(i, Math.min(i + digitTransaksi, message2.length())));
}
System.out.println("Source : " + source);
} catch (Exception e) {
e.printStackTrace();
}
for (String str3 : source) {
if (source.contains(noRek.substring(digitRek)) {
diff1.add(str3);
}
}
System.out.println("Final : " + diff1);
}
I excpet the output of the set diff1 is like this
SET 3 = [1234567890U0111, 1234567890U0112, 1234567890U0113,1234567890U0114, 1234567890U0115, 1234567890B0111, 1234567891B0111, 1234567892B0113, 1234567892B0112, 1234567892B0111]
but actual output is same like SET 2.
In simple way I need compare SET 2 with combination, first 10 digit is account number, then next charachter 1 digit is code, then the rest of number is auto generated. That's mean the length combination SET 2 is 15 digit, and combination SET 1 is 10 digit, then set 1 is data of account number, I need get all transaction from account number in set 2.
SET 1 is data all of account and
SET 2 is data of transaction combination
You can solve this by using stream and filter
Set<String> diff1 = source.stream().filter(str -> {
if (str.length() > 10) {
String account = str.substring(0, 10);
return noRek.contains(account);
}
return false;
}).collect(Collectors.toSet());

Java - renaming output file if name already exists with an increment, taking into account existing increments

building an Android app i came across the need to do some file copying. I would like a way to get new filenames in the event of a filename allready being used by adding a "(increment)" string in the filename. for example
text.txt ---> text(1).txt
The algorith should account for the following
1) if text.txt exists the new file name should NEVER be text.txt(1)
2) if text(1).txt exists then new filename should be text(2).txt not text(1)(1).txt
3) if text(1)foo.txt exists the new filename should be text(1)foo(1).txt
I've allready done the first but I'm having difficulties with the second. Regular expressions is not my strong suit!(It's not mandatory to use Regex. every approach is welcome) Some help ?
ANSWER:
combining my original code and one of the answers here I ended up with this which works very well for me in all cases regardless of file having an extension or not:
public static File getFinalNewDestinationFile(File destinationFolder, File fileToCopy){
String destFolderPath = destinationFolder.getAbsolutePath()+File.separator;
File newFile = new File(destFolderPath + fileToCopy.getName());
String filename=fileToCopy.getName();
String nameWithoutExtentionOrIncrement;
String extension = getFileExtension(filename);
if(extension!=null){
extension="."+extension;
int extInd = filename.lastIndexOf(extension);
nameWithoutExtentionOrIncrement = new StringBuilder(filename).replace(extInd, extInd+extension.length(),"").toString();
}
else{
extension="";
nameWithoutExtentionOrIncrement = filename;
}
int c=0;
int indexOfClose = nameWithoutExtentionOrIncrement.lastIndexOf(")");
int indexOfOpen = nameWithoutExtentionOrIncrement.lastIndexOf("(");
if(indexOfClose!=-1 && indexOfClose!=-1 && indexOfClose==nameWithoutExtentionOrIncrement.length()-1 && indexOfClose > indexOfOpen && indexOfOpen!=0){
String possibleNumber = nameWithoutExtentionOrIncrement.substring(indexOfOpen+1, indexOfClose);
try{
c = Integer.parseInt(possibleNumber);
nameWithoutExtentionOrIncrement=nameWithoutExtentionOrIncrement.substring(0, indexOfOpen);
}catch(Exception e){c=0;}
}
while(newFile.exists()){
c++;
String path = destFolderPath + nameWithoutExtentionOrIncrement +"(" + Integer.toString(c) + ")" + extension;
newFile = new File(path);
}
return newFile;
}
public static String getFileExtension(String filename) {
if (filename == null) { return null; }
int lastUnixPos = filename.lastIndexOf('/');
int lastWindowsPos = filename.lastIndexOf('\\');
int indexOfLastSeparator = Math.max(lastUnixPos, lastWindowsPos);
int extensionPos = filename.lastIndexOf('.');
int lastSeparator = indexOfLastSeparator;
int indexOfExtension = lastSeparator > extensionPos ? -1 : extensionPos;
int index = indexOfExtension;
if (index == -1) {
return null;
} else {
return filename.substring(index + 1).toLowerCase();
}
}
Using one regex pattern:
final static Pattern PATTERN = Pattern.compile("(.*?)(?:\\((\\d+)\\))?(\\.[^.]*)?");
String getNewName(String filename) {
if (fileExists(filename)) {
Matcher m = PATTERN.matcher(filename);
if (m.matches()) {
String prefix = m.group(1);
String last = m.group(2);
String suffix = m.group(3);
if (suffix == null) suffix = "";
int count = last != null ? Integer.parseInt(last) : 0;
do {
count++;
filename = prefix + "(" + count + ")" + suffix;
} while (fileExists(filename));
}
}
return filename;
}
The regex pattern explanation:
(.*?) a non greedy "match everything" starting at the beginning
(?:\\((\\d+)\\))? a number in parenthesis (optional)
(?:____________) - is a non capturing group
___\\(______\\)_ - matches ( and )
______(\\d+)____ - matches and captures the one or more digits
(\\.[^.]+)? a dot followed by anything but a dot (optional)
Here's one way of doing it:
String fileName;
File file = new File(fileName);
if(file.exists()) {
int dot = fileName.lastIndexOf('.'), open = fileName.lastIndexOf('('), incr;
boolean validNum = false;
if(fileName.charAt(dot-1) == ')' && open != -1){
String n = fileName.substring(open+1, dot-1);
try {
incr = Integer.parseInt(n);
validNum = true;
} catch(NumberFormatException e) {
validNum = false;
}
}
if(validNum) {
String pre = fileName.substring(0, open+1), post = fileName.substring(0, dot-1);
while(new File(pre + ++incr + post).exists());
fileName = pre + incr + post;
} else {
fileName = fileName.substring(0, dot) + "(1)" + fileName.substring(dot);
}
}
I assume a couple of things:
1) A method called fileExists(String fileName) is available. It returns true if a file with the specified name is already present in the file system.
2) There is a constant called FILE_NAME which in your example case is equal to "text".
if (!fileExists(FILE_NAME)) {
//create file with FILE_NAME.txt as name
}
int availableIndex = 1;
while (true) {
if (!fileExists(currentName)) {
//create file with FILE_NAME(availableIndex).txt
break;
}
availableIndex++;
}
I am not very sure about Android but since its a Java program, you may be able to create File object of the directory in which you want to write.
Once you have this you can see the list of file names already present inside it and other related information. Then you can decide the file name as per your above logic.
File dir = new File("<dir-path>");
if(dir.isDirectory()){
String[] files = dir.list();
for(String fileName : files){
<logic for finding filename>
}
}
If all filenames have an extenstion you could do something like this (just an example you will have to change it to work in your case):
public static void main(String[] args)
{
String test = "test(1)foo.txt";
String test1 = "test(1)foo(1).txt";
Pattern pattern = Pattern.compile("((?<=\\()\\d+(?=\\)\\.))");
Matcher matcher = pattern.matcher(test);
String fileOutput = "";
String temp = null;
int newInt = -1;
while(matcher.find())
{
temp = matcher.group(0);
}
if(temp != null)
{
newInt = Integer.parseInt(temp);
newInt++;
fileOutput = test.replaceAll("\\(\\d+\\)(?=\\.(?!.*\\.))", "(" + newInt + ")");
}
else
{
fileOutput = test;
}
System.out.println(fileOutput);
matcher = pattern.matcher(test1);
fileOutput = "";
temp = null;
while(matcher.find())
{
temp = matcher.group(0);
}
if(temp != null)
{
newInt = Integer.parseInt(temp);
newInt++;
fileOutput = test1.replaceAll("\\(\\d+\\)(?=\\.(?!.*\\.))", "(" + newInt + ")");
}
else
{
fileOutput = test1;
}
System.out.println(fileOutput);
}
Output:
test(1)foo.txt
test(1)foo(2).txt
This uses regex to look for a number in the () right before the last ..
Update
replaceAll() changed to handle case where there is a . after the first (1) in test(1).foo(1).txt.

Using the JGIT, how can I retrieve the line numbers of added/deleted lines

Assuming the following piece of code is committed to a Git repository:
int test(){
int a = 3;
int b = 4;
int c = a + b;
return c;
}
and is later updated to
int test(){
return 7;
}
I currently have a method which uses the JGit API in order to access the Git repository where the above are committed and outputs a string which is similar to the following:
int test(){
-int a = 3;
-int b = 4;
-int c = a + b;
-return c;
+return 7;
}
Now, my requirements have changed and would like to know the line numbers of the changed lines only. So I would want something like the following:
2 -int a = 3;
3 -int b = 4;
4 -int c = a + b;
5 -return c;
2 +return 7;
Basically, the same information that the GitHub application gives when an update is made.
Any help would be greatly appreciated :)
snippet of how the -/+ lines are computed:
String oldHash = "ee3e216ab5047748a22e9ec5ad3e92834704f0cc";
Git git = null;
try {
//the path where the repo is.
git = Git.open(new File("C:\\Users\\Administrator\\Documents\\GitHub\\Trial"));
} catch (IOException e1) {
e1.printStackTrace();
}
Repository repository = git.getRepository();
ObjectId old = null;
ObjectId head = null;
//a new reader to read objects from getObjectDatabase()
ObjectReader reader = repository.newObjectReader();
//Create a new parser.
CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
CanonicalTreeParser newTreeIter = new CanonicalTreeParser();
List<DiffEntry> diffs = null;
try {
//parse a git repository string and return an ObjectId
old = repository.resolve(oldHash + "^{tree}");
head = repository.resolve("HEAD^{tree}");
//Reset this parser to walk through the given tree
oldTreeIter.reset(reader, old);
newTreeIter.reset(reader, head);
diffs = git.diff()//Returns a command object to execute a diff command
.setNewTree(newTreeIter)
.setOldTree(oldTreeIter)
.call();//returns a DiffEntry for each path which is different
} catch (RevisionSyntaxException | IOException | GitAPIException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//DiffLineCountFilter d = new DiffLineCountFilter();
//out is the stream the formatter will write to
ByteArrayOutputStream out = new ByteArrayOutputStream();
//Create a new formatter with a default level of context.
DiffFormatter df = new DiffFormatter(out);
//Set the repository the formatter can load object contents from.
df.setRepository(git.getRepository());
ArrayList<String> diffText = new ArrayList<String>();
//A DiffEntry is 'A value class representing a change to a file' therefore for each file you have a diff entry
for(DiffEntry diff : diffs)
{
try {
//Format a patch script for one file entry.
df.format(diff);
RawText r = new RawText(out.toByteArray());
r.getLineDelimiter();
diffText.add(out.toString());
out.reset();
} catch (IOException e) {
e.printStackTrace();
}
}
You need to do the difference between the A line indexes and B line indexes from the diff result:
int linesAdded = 0;
int linesDeleted = 0;
int filesChanged = 0;
try {
repo = new FileRepository(new File("repo/.git"));
RevWalk rw = new RevWalk(repo);
RevCommit commit = rw.parseCommit(repo.resolve("486817d67b")); // Any ref will work here (HEAD, a sha1, tag, branch)
RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE);
df.setRepository(repo);
df.setDiffComparator(RawTextComparator.DEFAULT);
df.setDetectRenames(true);
List<DiffEntry> diffs;
diffs = df.scan(parent.getTree(), commit.getTree());
filesChanged = diffs.size();
for (DiffEntry diff : diffs) {
for (Edit edit : df.toFileHeader(diff).toEditList()) {
linesDeleted += edit.getEndA() - edit.getBeginA();
linesAdded += edit.getEndB() - edit.getBeginB();
}
}
} catch (IOException e1) {
throw new RuntimeException(e1);
}
Just a tip for anyone who might have this problem. I did not manage to get the line numbers of the added and deleted lines but I did manage to get a string which contains only the added and deleted lines without the other lines which were not changed.
This was simply done by adding the line:
df.setContext(0);
in the snippet I provided above right before the line
df.format(diff);
I do it this way but I don't know if it is correct
public void linesChangeInFile(Git git, List<RevCommit> commits, String fileName, String pathRepository) {
try {
List<RevCommit> commitsComparer = new ArrayList<>();
List<String> linesChange = new ArrayList<>();
for (int i = 0; i < commits.size() - 1; i++) {
ObjectId commitIDOld = commits.get(i).getId();
if (Validador.isFileExistInCommit(commits.get(i), getRepository(), fileName)) {
if (i != commits.size() - 1 && !commitsComparer.contains(commits.get(i))) {
ObjectId commitIDNew = commits.get(i + 1);
commitsComparer.add(commits.get(i));
linesChange.add(diff(git, commitIDOld.getName(), commitIDNew.getName(), fileName));
}
try (final FileInputStream input = new FileInputStream(pathRepository + "\\" + fileName)) {
currentLines = IOUtils.readLines(input, "UTF-8").size();
}
}
}
Integer sumLinesAdd = 0;
Integer sumLinesDel = 0;
for (String lineChange : linesChange) {
String[] lChange = lineChange.split(";");
sumLinesAdd += Integer.parseInt(lChange[0]);
sumLinesDel += Integer.parseInt(lChange[1]);
}
System.out.println("Lines Add total:" + sumLinesAdd);
System.out.println("Lines Del total:" + sumLinesDel);
System.out.println("Total lines change:" + (sumLinesAdd + sumLinesDel));
} catch (RevisionSyntaxException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private String diff(Git git, String commitIDOld, String commitIDNew, String fileName) {
int linesAdded = 0;
int linesDeleted = 0;
DiffFormatter df = null;
try {
AbstractTreeIterator oldTreeParser = prepareTreeParser(getRepository(), commitIDOld);
AbstractTreeIterator newTreeParser = prepareTreeParser(getRepository(), commitIDNew);
List<DiffEntry> diffs = git.diff().setOldTree(oldTreeParser).setNewTree(newTreeParser)
.setPathFilter(PathFilter.create(fileName)).call();
df = new DiffFormatter(DisabledOutputStream.INSTANCE);
df.setRepository(getRepository());
df.setDiffComparator(RawTextComparator.DEFAULT);
df.setDetectRenames(true);
for (DiffEntry entry : diffs) {
// System.out.println("Entry: " + entry + ", from: " + entry.getOldId() + ", to:
// " + entry.getNewId());
// try (DiffFormatter formatter = new DiffFormatter(System.out)) {
// formatter.setContext(0);
// formatter.setRepository(repository);
// formatter.format(entry);
// }
for (Edit edit : df.toFileHeader(entry).toEditList()) {
linesDeleted += edit.getEndA() - edit.getBeginA();
linesAdded += edit.getEndB() - edit.getBeginB();
}
}
} catch (IOException | GitAPIException e) {
System.err.println("Error:" + e.getMessage());
}
return linesAdded + ";" + linesDeleted;
}

How to find latest jar version of jars by java program?

In my project has 40 to 50 jar files available, It takes lot of time to find out latest version of each jar at every time. Can u any one help me to write a java program for this?
You may want to just use maven : http://maven.apache.org/
Or an other dependencies manager, like Ivy.
At the time of ant-build please call this method
public void ExpungeDuplicates(String filePath) {
Map<String,Integer> replaceJarsMap = null;
File folder = null;
File[] listOfFiles = null;
List<String> jarList = new ArrayList<String>();
String files = "";
File deleteFile = null;
Iterator<String> mapItr = null;
//String extension ="jar";
try {
folder = new File(filePath);
listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
files = listOfFiles[i].getName();
jarList.add(files);
}
}
if (jarList.size() > 0) {
replaceJarsMap = PatternClassifier.findDuplicatesOrLowerVersion(jarList);
System.err.println("Duplicate / Lower Version - Total Count : "+replaceJarsMap.size());
mapItr = replaceJarsMap.keySet().iterator();
while (mapItr.hasNext()) {
String key = mapItr.next();
int repeat = replaceJarsMap.get(key);
System.out.println( key +" : "+repeat);
for (int i = 0; i <repeat; i++) {
deleteFile = new File(filePath + System.getProperty ("file.separator")+key);
try{
if (deleteFile != null && deleteFile.exists()){
if(deleteFile.delete()){
System.err.println(key +" deleted");
}
}
}catch (Exception e) {
}
}
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
You only need to give the path of your Lib to this function.This method will find all the duplicate or lower version of of file.
And the crucial function is given below...Which finds out the duplicates from the list of files you provided.
public static Map<String,Integer> findDuplicatesOrLowerVersion(List<String> fileNameList) {
List<String> oldJarList = new ArrayList<String>();
String cmprTemp[] = null;
boolean match = false;
String regex = "",regexFileType = "",verInfo1 = "",verInfo2 = "",compareName = "",tempCompareName = "",tempJarName ="";
Map<String,Integer> duplicateEntryMap = new HashMap<String, Integer>();
int count = 0;
Collections.sort(fileNameList, Collections.reverseOrder());
try{
int size = fileNameList.size();
for(int i = 0;i<size;i++){
cmprTemp = fileNameList.get(i).split("[0-9\\._]*");
for(String s : cmprTemp){
compareName += s;
}
regex = "^"+compareName+"[ajr0-9_\\-\\.]*";
regexFileType = "[0-9a-zA-Z\\-\\._]*\\.jar$";
if( fileNameList.get(i).matches(regexFileType) && !oldJarList.contains(fileNameList.get(i))){
for(int j = i+1 ;j<size;j++){
cmprTemp = fileNameList.get(j).split("[0-9\\._]*");
for(String s : cmprTemp){
tempCompareName += s;
}
match = (fileNameList.get(j).matches(regexFileType) && tempCompareName.matches(regex));
if(match){
cmprTemp = fileNameList.get(i).split("[a-zA-Z\\-\\._]*");
for(String s : cmprTemp){
verInfo1 += s;
}
verInfo1 += "000";
cmprTemp = fileNameList.get(j).split("[a-zA-Z\\-\\._]*");
for(String s : cmprTemp){
verInfo2 += s;
}
verInfo2 += "000";
int length = 0;
if(verInfo1.length()>verInfo2.length()){
length = verInfo2.length();
}else{
length = verInfo1.length();
}
if(Long.parseLong(verInfo1.substring(0,length))>=Long.parseLong(verInfo2.substring(0,length))){
count = 0;
if(!oldJarList.contains(fileNameList.get(j))){
oldJarList.add(fileNameList.get(j));
duplicateEntryMap.put(fileNameList.get(j),++count);
}else{
count = duplicateEntryMap.get(fileNameList.get(j));
duplicateEntryMap.put(fileNameList.get(j),++count);
}
}else{
tempJarName = fileNameList.get(i);
}
match = false;verInfo1 = "";verInfo2 = "";
}
tempCompareName = "";
}
if(tempJarName!=null && !tempJarName.equals("")){
count = 0;
if(!oldJarList.contains(fileNameList.get(i))){
oldJarList.add(fileNameList.get(i));
duplicateEntryMap.put(fileNameList.get(i),++count);
}else{
count = dupl icateEntryMap.get(fileNameList.get(i));
duplicateEntryMap.put(fileNameList.get(i),++count);
}
tempJarName = "";
}
}
compareName = "";
}
}catch (Exception e) {
e.printStackTrace();
}
return duplicateEntryMap;
}
What findDuplicatesOrLowerVersion(List fileNameList) function task - Simply it found the duplicates and passting a map which contains the name of the file and number of time the lower version repeats.
Try this. The remaining file exist in the folder should be latest or files with out duplicates.Am using this for finding the oldest files.on the basis of that it will find the old and delete it.
This am only checking the name..Futher improvement you can made.
Where PatternClassifier is a class which contains the second method given here.

Categories

Resources