560d85363c184829be894c068614536a1a43d871
[mediacube.git] /
1 package user.jobengine.server.steps;\r
2 \r
3 import java.io.File;\r
4 import java.io.IOException;\r
5 import java.nio.file.DirectoryStream;\r
6 import java.nio.file.FileVisitResult;\r
7 import java.nio.file.FileVisitor;\r
8 import java.nio.file.Files;\r
9 import java.nio.file.Path;\r
10 import java.nio.file.Paths;\r
11 import java.nio.file.SimpleFileVisitor;\r
12 import java.nio.file.attribute.BasicFileAttributes;\r
13 import java.text.ParseException;\r
14 import java.text.SimpleDateFormat;\r
15 import java.util.ArrayList;\r
16 import java.util.Collections;\r
17 import java.util.Date;\r
18 import java.util.List;\r
19 \r
20 import org.apache.commons.io.FileUtils;\r
21 import org.apache.commons.lang.StringUtils;\r
22 import org.apache.logging.log4j.LogManager;\r
23 import org.apache.logging.log4j.Logger;\r
24 import org.apache.logging.log4j.Marker;\r
25 \r
26 import user.jobengine.server.IJobEngine;\r
27 import user.jobengine.server.IJobRuntime;\r
28 import user.jobengine.server.steps.MetadataTypeDetector.MetadataType;\r
29 \r
30 public class ProjectCleanupMountedLocationStep extends JobStep implements FileVisitor<Path> {\r
31 \r
32         private static final Logger logger = LogManager.getLogger();\r
33         private static final String DATEFORMAT = "yyyyMMdd";\r
34         private static final String DOT = ".";\r
35         private static final String STATUSFOLDER = ".STATUS";\r
36         private static final String KILLDATEEXT = ".killdate";\r
37         private Marker marker;\r
38         final int[] allCount = { 0 };\r
39         final int[] currentCount = { 0 };\r
40         private Path sourcePath;\r
41         private SimpleDateFormat dateFormat;\r
42 \r
43         private Date checkExpiration(List<Path> killDateFiles) {\r
44                 Date killDate = null;\r
45                 for (Path killDateFile : killDateFiles) {\r
46                         Date currentKillDate = getKillDate(killDateFile);\r
47                         if (currentKillDate == null)\r
48                                 continue;\r
49                         if ((killDate != null && currentKillDate.after(killDate)) || killDate == null)\r
50                                 killDate = currentKillDate;\r
51                 }\r
52                 return new Date().after(killDate) ? killDate : null;\r
53         }\r
54 \r
55         @StepEntry\r
56         public Object[] execute(String sourceFolder, IJobEngine jobEngine, IJobRuntime jobRuntime) throws Exception {\r
57                 marker = jobRuntime.getMarker();\r
58                 sourcePath = Paths.get(sourceFolder);\r
59                 DirectoryStream<Path> directoryStream = null;\r
60                 if (StringUtils.isBlank(sourcePath.toString())) {\r
61                         logger.error(marker, "A folyamat 'sourcePath' bemeneti paramétere üres.");\r
62                         throw new NullPointerException("System is not configured properly, 'sourceFolder' input parameter missing.");\r
63                 }\r
64 \r
65                 if (!sourcePath.toFile().exists() || !sourcePath.toFile().isDirectory()) {\r
66                         logger.error(marker, "A {} mappa nem létezik.", sourceFolder);\r
67                         throw new NullPointerException(String.format("Directory %s not exists.", sourceFolder));\r
68                 }\r
69                 try {\r
70                         setProgress(1);\r
71                         dateFormat = new SimpleDateFormat(DATEFORMAT);\r
72                         Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() {\r
73                                 @Override\r
74                                 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\r
75                                         allCount[0]++;\r
76                                         return super.visitFile(file, attrs);\r
77                                 }\r
78                         });\r
79                         Files.walkFileTree(sourcePath, this);\r
80                 } catch (Exception e) {\r
81                         logger.catching(e);\r
82                         logger.error(marker, "Az '{}' mappa elérése sikertelen. A rendszer hibaüzenete: {}", sourcePath, e.getMessage());\r
83                         throw e;\r
84                 } finally {\r
85                         if (directoryStream != null) {\r
86                                 try {\r
87                                         directoryStream.close();\r
88                                 } catch (IOException e) {\r
89                                 }\r
90                         }\r
91                 }\r
92                 return null;\r
93         }\r
94 \r
95         private Date getKillDate(Path killDateFile) {\r
96                 String fileName = killDateFile.getFileName().toString();\r
97                 int end = fileName.lastIndexOf(DOT);\r
98                 if (end < 1)\r
99                         return null;\r
100                 int start = fileName.lastIndexOf(DOT, end - 1);\r
101                 if (start < 0)\r
102                         return null;\r
103                 String strKillDate = fileName.substring(start + 1, end);\r
104                 Date result = null;\r
105                 if (StringUtils.isNumeric(strKillDate)) {\r
106                         try {\r
107                                 result = dateFormat.parse(strKillDate);\r
108                         } catch (ParseException e) {\r
109                                 logger.error(marker, "A {} fájl 'killdate' állománya hibás formátumú, a {} karaktersorozat nem konvertálható dátummá.", fileName, strKillDate);\r
110                                 return null;\r
111                         }\r
112                 } else\r
113                         logger.error(marker, "A {} fájl 'killdate' állománya hibás formátumú, az dátum helyett ez áll: '{}'.", fileName, strKillDate);\r
114                 return result;\r
115         }\r
116 \r
117         private List<Path> getKillDateFiles(Path filePath) {\r
118                 String killDateFilePattern = String.format("%s.*%s", filePath.getFileName().toString(), KILLDATEEXT);\r
119                 List<Path> result = new ArrayList<>();\r
120                 Path statusPath = null;\r
121                 try {\r
122                         statusPath = Paths.get(filePath.getParent().toString(), STATUSFOLDER);\r
123                 } catch (Exception e) {\r
124                         logger.catching(e);\r
125                         return null;\r
126                 }\r
127                 File statusPathFile = statusPath.toFile();\r
128                 if (statusPathFile.exists() && statusPathFile.isDirectory()) {\r
129                         try (DirectoryStream<Path> stream = Files.newDirectoryStream(statusPath, killDateFilePattern)) {\r
130                                 stream.forEach(p -> result.add(p));\r
131                         } catch (Exception e) {\r
132                                 logger.catching(e);\r
133                         }\r
134                 }\r
135                 Collections.sort(result);\r
136                 return result;\r
137         }\r
138 \r
139         private Path getProjectRootPath(Path filePath) {\r
140                 Path result = null;\r
141                 if (filePath.getNameCount() > sourcePath.getNameCount()) {\r
142                         String dir = filePath.getName(sourcePath.getNameCount()).toString();\r
143                         String[] tokens = dir.split("-");\r
144                         if (tokens.length != 0 && MetadataTypeDetector.GuessMetadataType(tokens[0]) == MetadataType.TrafficPromo)\r
145                                 result = Paths.get(sourcePath.toAbsolutePath().toString(), dir);\r
146                 }\r
147                 return result;\r
148         }\r
149 \r
150         @Override\r
151         public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {\r
152                 return FileVisitResult.CONTINUE;\r
153         }\r
154 \r
155         @Override\r
156         public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {\r
157                 if (dir.equals(sourcePath))\r
158                         return FileVisitResult.CONTINUE;\r
159 \r
160                 Path parent = getProjectRootPath(dir);\r
161                 if (parent == null) {\r
162                         System.out.println("Skipping " + dir);\r
163                         return FileVisitResult.SKIP_SUBTREE;\r
164                 }\r
165 \r
166                 return FileVisitResult.CONTINUE;\r
167         }\r
168 \r
169         private boolean processPathItem(Path filePath) {\r
170                 currentCount[0]++;\r
171                 setProgress(currentCount[0] * 100 / allCount[0]);\r
172 \r
173                 if (filePath.toFile().isDirectory() || !filePath.toString().toUpperCase().endsWith(".EZP"))\r
174                         return false;\r
175 \r
176                 List<Path> killDateFiles = getKillDateFiles(filePath);\r
177                 if (killDateFiles == null || killDateFiles.size() == 0) {\r
178                         logger.warn(marker, "A {} fájlhoz nem található 'killdate' állomány.", filePath);\r
179                         return false;\r
180                 }\r
181 \r
182                 if (killDateFiles.size() != 1)\r
183                         logger.warn(marker, "A {} fájlhoz több 'killdate' állomány található, a legújabb dátum határozza meg a törlés időpontját.", filePath);\r
184 \r
185                 Date killDate = checkExpiration(killDateFiles);\r
186                 if (killDate == null)\r
187                         return false;\r
188 \r
189                 Path parent = getProjectRootPath(filePath);\r
190                 if (parent != null) {\r
191                         Path pathToDelete = Paths.get(sourcePath.toAbsolutePath().toString(), filePath.getName(sourcePath.getNameCount()).toString());\r
192                         try {\r
193                                 FileUtils.deleteDirectory(pathToDelete.toFile());\r
194                                 logger.info(marker, "A {} mappa sikeresen törlődött", pathToDelete);\r
195                         } catch (IOException e) {\r
196                                 logger.error(marker, "A {} mappa törlése nem lehetséges, a rendszer üzenete: {}", pathToDelete, e.getMessage());\r
197                                 logger.error(e);\r
198                         }\r
199                 } else\r
200                         logger.warn(marker, "A {} fájlhoz nem határozható meg a törlendő szülőkönyvtár.", filePath);\r
201                 return true;\r
202         }\r
203 \r
204         @Override\r
205         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\r
206                 processPathItem(file);\r
207                 return FileVisitResult.CONTINUE;\r
208         }\r
209 \r
210         @Override\r
211         public FileVisitResult visitFileFailed(Path file, IOException e) throws IOException {\r
212                 logger.error(marker, "A {} fájl nem érhető el. A rendszer hibaüzenete: {}", file.toString(), e.getMessage());\r
213                 return FileVisitResult.CONTINUE;\r
214         }\r
215 }\r