1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.sys.businessobject.lookup;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.text.ParseException;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Date;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Properties;
27
28 import org.apache.commons.io.DirectoryWalker;
29 import org.apache.commons.io.IOCase;
30 import org.apache.commons.io.filefilter.AbstractFileFilter;
31 import org.apache.commons.io.filefilter.FileFilterUtils;
32 import org.apache.commons.io.filefilter.IOFileFilter;
33 import org.apache.commons.io.filefilter.WildcardFileFilter;
34 import org.apache.commons.lang.StringUtils;
35 import org.kuali.ole.sys.batch.BatchFile;
36 import org.kuali.ole.sys.batch.BatchFileUtils;
37 import org.kuali.ole.sys.batch.service.BatchFileAdminAuthorizationService;
38 import org.kuali.ole.sys.util.KfsDateUtils;
39 import org.kuali.rice.core.api.datetime.DateTimeService;
40 import org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl;
41 import org.kuali.rice.kns.lookup.HtmlData;
42 import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
43 import org.kuali.rice.kns.web.ui.Field;
44 import org.kuali.rice.kns.web.ui.Row;
45 import org.kuali.rice.krad.bo.BusinessObject;
46 import org.kuali.rice.krad.util.GlobalVariables;
47 import org.kuali.rice.krad.util.KRADConstants;
48 import org.kuali.rice.krad.util.UrlFactory;
49
50 public class BatchFileLookupableHelperServiceImpl extends AbstractLookupableHelperServiceImpl {
51 protected DateTimeService dateTimeService;
52 protected BatchFileAdminAuthorizationService batchFileAdminAuthorizationService;
53
54 @Override
55 public List<? extends BusinessObject> getSearchResults(Map<String, String> fieldValues) {
56 List<BatchFile> results = new ArrayList<BatchFile>();
57
58 IOFileFilter filter = FileFilterUtils.fileFileFilter();
59
60 IOFileFilter pathBasedFilter = getPathBasedFileFilter();
61 if (pathBasedFilter != null) {
62 filter = FileFilterUtils.andFileFilter(filter, pathBasedFilter);
63 }
64
65 String fileNamePattern = fieldValues.get("fileName");
66 IOFileFilter fileNameBasedFilter = getFileNameBasedFilter(fileNamePattern);
67 if (fileNameBasedFilter != null) {
68 filter = FileFilterUtils.andFileFilter(filter, fileNameBasedFilter);
69 }
70
71 String lastModifiedDate = fieldValues.get("lastModifiedDate");
72 IOFileFilter lastModifiedDateBasedFilter = getLastModifiedDateBasedFilter(lastModifiedDate);
73 if (lastModifiedDateBasedFilter != null) {
74 filter = FileFilterUtils.andFileFilter(filter, lastModifiedDateBasedFilter);
75 }
76
77 BatchFileFinder finder = new BatchFileFinder(results, filter);
78 List<File> rootDirectories = BatchFileUtils.retrieveBatchFileLookupRootDirectories();
79 finder.find(rootDirectories);
80
81 return results;
82 }
83
84 protected IOFileFilter getPathBasedFileFilter() {
85 List<File> selectedFiles = getSelectedDirectories(getSelectedPaths());
86 if (selectedFiles.isEmpty()) {
87 return null;
88 }
89 IOFileFilter fileFilter = null;
90 for (File selectedFile : selectedFiles) {
91 IOFileFilter subFilter = new SubDirectoryFileFilter(selectedFile);
92 if (fileFilter == null) {
93 fileFilter = subFilter;
94 }
95 else {
96 fileFilter = FileFilterUtils.orFileFilter(fileFilter, subFilter);
97 }
98 }
99 return fileFilter;
100 }
101
102 protected IOFileFilter getFileNameBasedFilter(String fileNamePattern) {
103 if (StringUtils.isNotBlank(fileNamePattern)) {
104 return new WildcardFileFilter(fileNamePattern, IOCase.INSENSITIVE);
105 }
106 return null;
107 }
108
109 protected IOFileFilter getLastModifiedDateBasedFilter(String lastModifiedDatePattern) {
110 if (StringUtils.isBlank(lastModifiedDatePattern)) {
111 return null;
112 }
113 try {
114 if (lastModifiedDatePattern.startsWith("<=")) {
115 String dateString = StringUtils.removeStart(lastModifiedDatePattern, "<=");
116 Date toDate = dateTimeService.convertToDate(dateString);
117 return new LastModifiedDateFileFilter(null, toDate);
118 }
119 if (lastModifiedDatePattern.startsWith(">=")) {
120 String dateString = StringUtils.removeStart(lastModifiedDatePattern, ">=");
121 Date fromDate = dateTimeService.convertToDate(dateString);
122 return new LastModifiedDateFileFilter(fromDate, null);
123 }
124 if (lastModifiedDatePattern.contains("..")) {
125 String[] dates = StringUtils.splitByWholeSeparator(lastModifiedDatePattern, "..", 2);
126 Date fromDate = dateTimeService.convertToDate(dates[0]);
127 Date toDate = dateTimeService.convertToDate(dates[1]);
128 return new LastModifiedDateFileFilter(fromDate, toDate);
129 }
130 }
131 catch (ParseException e) {
132 throw new RuntimeException("Can't parse date", e);
133 }
134 throw new RuntimeException("Unable to perform search using last modified date " + lastModifiedDatePattern);
135 }
136
137 protected List<File> getSelectedDirectories(String[] selectedPaths) {
138 List<File> directories = new ArrayList<File>();
139 if (selectedPaths != null) {
140 for (String selectedPath : selectedPaths) {
141 File directory = new File(BatchFileUtils.resolvePathToAbsolutePath(selectedPath));
142 if (!directory.exists()) {
143 throw new RuntimeException("Non existent directory " + BatchFileUtils.resolvePathToAbsolutePath(selectedPath));
144 }
145 directories.add(directory);
146 }
147 }
148 return directories;
149 }
150
151
152
153
154
155 protected String[] getSelectedPaths() {
156 List<Row> rows = getRows();
157 if (rows == null) {
158 return null;
159 }
160 for (Row row : rows) {
161 for (Field field : row.getFields()) {
162 if ("path".equals(field.getPropertyName()) && Field.MULTISELECT.equals(field.getFieldType())) {
163 String[] values = field.getPropertyValues();
164 return values;
165 }
166 }
167 }
168 return null;
169 }
170
171 protected class SubDirectoryFileFilter extends AbstractFileFilter {
172 private File superDirectory;
173
174 public SubDirectoryFileFilter(File superDirectory) {
175 this.superDirectory = superDirectory.getAbsoluteFile();
176 }
177
178 @Override
179 public boolean accept(File file) {
180 file = file.getAbsoluteFile();
181 file = file.getParentFile();
182 while (file != null) {
183 if (file.equals(superDirectory)) {
184 return true;
185 }
186 file = file.getParentFile();
187 }
188 return false;
189 }
190 }
191
192 protected class LastModifiedDateFileFilter extends AbstractFileFilter {
193 private Date fromDate;
194 private Date toDate;
195
196 public LastModifiedDateFileFilter(Date fromDate, Date toDate) {
197 this.fromDate = fromDate;
198 this.toDate = toDate;
199 }
200
201 @Override
202 public boolean accept(File file) {
203 Date lastModifiedDate = KfsDateUtils.clearTimeFields(new Date(file.lastModified()));
204
205 if (fromDate != null && fromDate.after(lastModifiedDate)) {
206 return false;
207 }
208 if (toDate != null && toDate.before(lastModifiedDate)) {
209 return false;
210 }
211 return true;
212 }
213 }
214
215 protected class BatchFileFinder extends DirectoryWalker {
216 private List<BatchFile> results;
217
218 public BatchFileFinder(List<BatchFile> results, IOFileFilter fileFilter) {
219 super(null, fileFilter, -1);
220 this.results = results;
221 }
222
223 public void find(Collection<File> rootDirectories) {
224 try {
225 for (File rootDirectory : rootDirectories) {
226 walk(rootDirectory, null);
227 }
228 }
229 catch (IOException e) {
230 throw new RuntimeException("Error performing lookup", e);
231 }
232 }
233
234
235
236
237 @Override
238 protected void handleFile(File file, int depth, Collection results) throws IOException {
239 super.handleFile(file, depth, results);
240 BatchFile batchFile = new BatchFile();
241 batchFile.setFile(file);
242 this.results.add(batchFile);
243 }
244 }
245
246 public void setDateTimeService(DateTimeService dateTimeService) {
247 this.dateTimeService = dateTimeService;
248 }
249
250 @Override
251 public List<HtmlData> getCustomActionUrls(BusinessObject businessObject, List pkNames) {
252 List<HtmlData> links = new ArrayList<HtmlData>();
253
254 BatchFile batchFile = (BatchFile) businessObject;
255 if (canDownloadFile(batchFile)) {
256 links.add(getDownloadUrl(batchFile));
257 }
258 if (canDeleteFile(batchFile)) {
259 links.add(getDeleteUrl(batchFile));
260 }
261 return links;
262 }
263
264 protected boolean canDownloadFile(BatchFile batchFile) {
265 return batchFileAdminAuthorizationService.canDownload(batchFile, GlobalVariables.getUserSession().getPerson());
266 }
267
268 protected boolean canDeleteFile(BatchFile batchFile) {
269 return batchFileAdminAuthorizationService.canDelete(batchFile, GlobalVariables.getUserSession().getPerson());
270 }
271
272 protected HtmlData getDownloadUrl(BatchFile batchFile) {
273 Properties parameters = new Properties();
274 parameters.put("filePath", BatchFileUtils.pathRelativeToRootDirectory(batchFile.retrieveFile().getAbsolutePath()));
275 parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, "download");
276 String href = UrlFactory.parameterizeUrl("../batchFileAdmin.do", parameters);
277 return new AnchorHtmlData(href, "download", "Download");
278 }
279
280 protected HtmlData getDeleteUrl(BatchFile batchFile) {
281 Properties parameters = new Properties();
282 parameters.put("filePath", BatchFileUtils.pathRelativeToRootDirectory(batchFile.retrieveFile().getAbsolutePath()));
283 parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, "delete");
284 String href = UrlFactory.parameterizeUrl("../batchFileAdmin.do", parameters);
285 return new AnchorHtmlData(href, "delete", "Delete");
286 }
287
288
289
290
291 @Override
292 public void validateSearchParameters(Map fieldValues) {
293 super.validateSearchParameters(fieldValues);
294
295 String[] selectedPaths = getSelectedPaths();
296 if (selectedPaths != null) {
297 for (String selectedPath : selectedPaths) {
298 String resolvedPath = BatchFileUtils.resolvePathToAbsolutePath(selectedPath);
299 if (!BatchFileUtils.isDirectoryAccessible(resolvedPath)) {
300 throw new RuntimeException("Can't access path " + selectedPath);
301 }
302 }
303 }
304 }
305
306
307
308
309
310 public void setBatchFileAdminAuthorizationService(BatchFileAdminAuthorizationService batchFileAdminAuthorizationService) {
311 this.batchFileAdminAuthorizationService = batchFileAdminAuthorizationService;
312 }
313 }