1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.net.ftp.parser;
19
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.io.FilenameFilter;
23 import java.io.InputStream;
24 import java.util.Arrays;
25 import java.util.Calendar;
26 import java.util.Comparator;
27 import java.util.TimeZone;
28
29 import org.apache.commons.net.ftp.FTP;
30 import org.apache.commons.net.ftp.FTPClientConfig;
31 import org.apache.commons.net.ftp.FTPFile;
32 import org.apache.commons.net.ftp.FTPFileFilters;
33 import org.apache.commons.net.ftp.FTPListParseEngine;
34 import org.junit.Test;
35
36
37
38
39
40
41 public class MLSDComparison {
42
43 private final Comparator<FTPFile> cmp = (o1, o2) -> {
44 final String n1 = o1.getName();
45 final String n2 = o2.getName();
46 return n1.compareTo(n2);
47 };
48
49
50
51
52
53
54
55
56
57 public boolean areEquivalent(final FTPFile a, final FTPFile b) {
58 return a.getName().equals(b.getName()) && areSame(a.getSize(), b.getSize(), -1L) &&
59
60
61 areSame(a.getTimestamp(), b.getTimestamp())
62
63
64
65 ;
66 }
67
68 private boolean areSame(final Calendar a, final Calendar b) {
69 return a == null || b == null || areSameDateTime(a, b);
70 }
71
72 private boolean areSame(final long a, final long b, final long d) {
73 return a == d || b == d || a == b;
74 }
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 private boolean areSameDateTime(final Calendar a, final Calendar b) {
95 final TimeZone UTC = TimeZone.getTimeZone("UTC");
96 final Calendar ac = Calendar.getInstance(UTC);
97 ac.setTime(a.getTime());
98 final Calendar bc = Calendar.getInstance(UTC);
99 bc.setTime(b.getTime());
100 return isSameDay(ac, bc) && isSameTime(ac, bc);
101 }
102
103 private void compareSortedLists(final FTPFile[] lst, final FTPFile[] mlst) {
104 Arrays.sort(lst, cmp);
105 Arrays.sort(mlst, cmp);
106 FTPFile first;
107 FTPFile second;
108 final int firstl = lst.length;
109 final int secondl = mlst.length;
110 int one = 0;
111 int two = 0;
112 first = lst[one++];
113 second = mlst[two++];
114 int cmp;
115 while (one < firstl || two < secondl) {
116
117
118 final String rl1 = first.getRawListing();
119 final String rl2 = second.getRawListing();
120 cmp = first.getName().compareTo(second.getName());
121 if (cmp == 0) {
122 if (first.getName().endsWith("HEADER.html")) {
123 cmp = 0;
124 }
125 if (!areEquivalent(first, second)) {
126
127
128 final long tdiff = first.getTimestamp().getTimeInMillis() - second.getTimestamp().getTimeInMillis();
129 System.out.println("Minutes diff " + tdiff / (1000 * 60));
130
131
132
133
134 }
135 if (one < firstl) {
136 first = lst[one++];
137 }
138 if (two < secondl) {
139 second = mlst[two++];
140 }
141 } else if (cmp < 0) {
142 if (!first.getName().startsWith(".")) {
143 System.out.println("1: " + rl1);
144 }
145 if (one < firstl) {
146 first = lst[one++];
147 }
148 } else {
149 System.out.println("2: " + rl2);
150 if (two < secondl) {
151 second = mlst[two++];
152 }
153 }
154 }
155 }
156
157 private boolean isSameDay(final Calendar a, final Calendar b) {
158 final int ad = a.get(Calendar.DAY_OF_MONTH);
159 final int bd = b.get(Calendar.DAY_OF_MONTH);
160 return a.get(Calendar.YEAR) == b.get(Calendar.YEAR) && a.get(Calendar.MONTH) == b.get(Calendar.MONTH) && ad == bd;
161 }
162
163 private boolean isSameTime(final Calendar a, final Calendar b) {
164 final int ah = a.get(Calendar.HOUR_OF_DAY);
165 final int bh = b.get(Calendar.HOUR_OF_DAY);
166 final int am = a.get(Calendar.MINUTE);
167 final int bm = b.get(Calendar.MINUTE);
168 final int as = a.get(Calendar.SECOND);
169 final int bs = b.get(Calendar.SECOND);
170
171 return ah == 0 && am == 0 && as == 0
172 || bh == 0 && bm == 0 && bs == 0
173 || ah == bh && am == bm;
174
175 }
176
177 @Test
178 public void testFile() throws Exception {
179 final File path = new File(DownloadListings.DOWNLOAD_DIR);
180 final FilenameFilter filter = (dir, name) -> name.endsWith("_mlsd.txt");
181 final File[] files = path.listFiles(filter);
182 if (files != null) {
183 for (final File mlsd : files) {
184
185 FTPListParseEngine engine = new FTPListParseEngine(MLSxEntryParser.getInstance());
186 try (InputStream is = new FileInputStream(mlsd)) {
187 engine.readServerList(is, FTP.DEFAULT_CONTROL_ENCODING);
188 }
189 final FTPFile[] mlsds = engine.getFiles(FTPFileFilters.ALL);
190 final File listFile = new File(mlsd.getParentFile(), mlsd.getName().replace("_mlsd", "_list"));
191 try (InputStream inputStream = new FileInputStream(listFile)) {
192 final FTPClientConfig cfg = new FTPClientConfig();
193 cfg.setServerTimeZoneId("GMT");
194 final UnixFTPEntryParser parser = new UnixFTPEntryParser(cfg);
195 engine = new FTPListParseEngine(parser);
196 engine.readServerList(inputStream, FTP.DEFAULT_CONTROL_ENCODING);
197 compareSortedLists(mlsds, engine.getFiles(FTPFileFilters.ALL));
198 }
199 }
200 }
201 }
202
203
204
205
206
207
208
209
210 }