1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.sys.batch.service.impl;
17
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.FileOutputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.OutputStream;
24 import java.util.ArrayList;
25 import java.util.Date;
26 import java.util.HashMap;
27 import java.util.LinkedHashMap;
28 import java.util.List;
29 import java.util.Map;
30
31 import org.kuali.ole.sys.OLEConstants;
32 import org.kuali.ole.sys.OLEConstants.SystemGroupParameterNames;
33 import org.kuali.ole.sys.batch.BatchInputFileSetType;
34 import org.kuali.ole.sys.batch.InitiateDirectoryBase;
35 import org.kuali.ole.sys.batch.service.BatchInputFileSetService;
36 import org.kuali.ole.sys.context.SpringContext;
37 import org.kuali.ole.sys.exception.FileStorageException;
38 import org.kuali.ole.sys.service.impl.OleParameterConstants;
39 import org.kuali.rice.core.api.config.property.ConfigurationService;
40 import org.kuali.rice.core.api.datetime.DateTimeService;
41 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
42 import org.kuali.rice.kim.api.identity.Person;
43 import org.kuali.rice.krad.exception.AuthorizationException;
44 import org.kuali.rice.krad.exception.ValidationException;
45 import org.kuali.rice.krad.util.GlobalVariables;
46
47
48
49
50 public class BatchInputFileSetServiceImpl extends InitiateDirectoryBase implements BatchInputFileSetService {
51 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BatchInputFileSetServiceImpl.class);
52
53 protected ConfigurationService kualiConfigurationService;
54
55
56
57
58
59
60
61
62
63
64 protected String generateFileName(Person user, BatchInputFileSetType inputType, String fileUserIdentifier, String fileType, Date creationDate) {
65 if (!isFileUserIdentifierProperlyFormatted(fileUserIdentifier)) {
66 throw new IllegalArgumentException("The file set identifier is not properly formatted: " + fileUserIdentifier);
67 }
68 return inputType.getDirectoryPath(fileType) + File.separator + inputType.getFileName(fileType, user.getPrincipalName(), fileUserIdentifier, creationDate);
69 }
70
71
72
73
74
75
76
77
78
79
80 protected String generateTempFileName(Person user, BatchInputFileSetType inputType, String fileUserIdentifier, String fileType, Date creationDate) {
81 if (!isFileUserIdentifierProperlyFormatted(fileUserIdentifier)) {
82 throw new IllegalArgumentException("The file set identifier is not properly formatted: " + fileUserIdentifier);
83 }
84 return getTempDirectoryName() + File.separator + inputType.getFileName(fileType, user.getPrincipalName(), fileUserIdentifier, creationDate);
85 }
86
87
88
89
90
91
92
93
94
95 protected String generateDoneFileName(Person user, BatchInputFileSetType inputType, String fileUserIdentifier, Date creationDate) {
96 if (!isFileUserIdentifierProperlyFormatted(fileUserIdentifier)) {
97 throw new IllegalArgumentException("The file set identifier is not properly formatted: " + fileUserIdentifier);
98 }
99 return inputType.getDoneFileDirectoryPath() + File.separator + inputType.getDoneFileName(user, fileUserIdentifier, creationDate);
100 }
101
102
103
104
105 public boolean isBatchInputTypeActive(BatchInputFileSetType batchInputFileSetType) {
106 if (batchInputFileSetType == null) {
107 LOG.error("an invalid(null) argument was given");
108 throw new IllegalArgumentException("an invalid(null) argument was given");
109 }
110 List<String> activeInputTypes = new ArrayList<String>( SpringContext.getBean(ParameterService.class).getParameterValuesAsString(OleParameterConstants.FINANCIAL_SYSTEM_BATCH.class, SystemGroupParameterNames.ACTIVE_INPUT_TYPES_PARAMETER_NAME) );
111
112 boolean activeBatchType = false;
113 if (activeInputTypes.size() > 0 && activeInputTypes.contains(batchInputFileSetType.getFileSetTypeIdentifer())) {
114 activeBatchType = true;
115 }
116
117 return activeBatchType;
118 }
119
120
121
122
123
124 public Map<String, String> save(Person user, BatchInputFileSetType inputType, String fileUserIdentifier, Map<String, InputStream> typeToStreamMap) throws AuthorizationException, FileStorageException {
125
126 prepareDirectories(getRequiredDirectoryNames());
127
128 Date creationDate = SpringContext.getBean(DateTimeService.class).getCurrentDate();
129
130 Map<String, File> typeToTempFiles = copyStreamsToTemporaryDirectory(user, inputType, fileUserIdentifier, typeToStreamMap, creationDate);
131
132
133 typeToStreamMap = null;
134
135 if (!inputType.validate(typeToTempFiles)) {
136 deleteTempFiles(typeToTempFiles);
137 LOG.error("Upload file validation failed for user " + user.getName() + " identifier " + fileUserIdentifier);
138 throw new ValidationException("File validation failed: " + GlobalVariables.getMessageMap().getErrorMessages());
139 }
140
141 byte[] buf = new byte[1024];
142
143 Map<String, String> typeToFileNames = new LinkedHashMap<String, String>();
144 Map<String, File> typeToFiles = new LinkedHashMap<String, File>();
145 try {
146 for (String fileType : inputType.getFileTypes()) {
147 File tempFile = typeToTempFiles.get(fileType);
148 String saveFileName = inputType.getDirectoryPath(fileType) + File.separator + tempFile.getName();
149 try {
150 InputStream fileContents = new FileInputStream(tempFile);
151 File fileToSave = new File(saveFileName);
152
153 copyInputStreamToFile(fileContents, fileToSave, buf);
154 fileContents.close();
155 typeToFileNames.put(fileType, saveFileName);
156 typeToFiles.put(fileType, fileToSave);
157 }
158 catch (IOException e) {
159 LOG.error("unable to save contents to file " + saveFileName, e);
160 throw new RuntimeException("errors encountered while writing file " + saveFileName, e);
161 }
162 }
163 }
164 finally {
165 deleteTempFiles(typeToTempFiles);
166 }
167
168 String doneFileName = inputType.getDoneFileDirectoryPath() + File.separator + inputType.getDoneFileName(user, fileUserIdentifier, creationDate);
169 File doneFile = new File(doneFileName);
170 try {
171 doneFile.createNewFile();
172
173 typeToFiles.put(OLEConstants.DONE_FILE_TYPE, doneFile);
174 }
175 catch (IOException e) {
176 LOG.error("unable to create done file", e);
177 throw new RuntimeException("unable to create done file", e);
178 }
179
180 inputType.process(typeToFiles);
181
182 return typeToFileNames;
183 }
184
185 protected Map<String, File> copyStreamsToTemporaryDirectory(Person user, BatchInputFileSetType inputType,
186 String fileUserIdentifier, Map<String, InputStream> typeToStreamMap, Date creationDate) throws FileStorageException {
187 Map<String, File> tempFiles = new HashMap<String, File>();
188
189 String tempDirectoryName = getTempDirectoryName();
190 File tempDirectory = new File(tempDirectoryName);
191 if (!tempDirectory.exists() || !tempDirectory.isDirectory()) {
192 LOG.error("Temporary Directory " + tempDirectoryName + " does not exist or is not a directory");
193 throw new RuntimeException("Temporary Directory " + tempDirectoryName + " does not exist or is not a directory");
194 }
195
196 byte[] buf = new byte[1024];
197
198 try {
199 for (String fileType : inputType.getFileTypes()) {
200 String tempFileName = generateTempFileName(user, inputType, fileUserIdentifier, fileType, creationDate);
201 InputStream source = typeToStreamMap.get(fileType);
202 File tempFile = new File(tempFileName);
203 copyInputStreamToFile(source, tempFile, buf);
204 tempFiles.put(fileType, tempFile);
205 }
206 }
207 catch (IOException e) {
208 LOG.error("Error creating temporary files", e);
209 throw new FileStorageException("Error creating temporary files",e);
210
211 }
212 return tempFiles;
213 }
214
215 protected void copyInputStreamToFile(InputStream source, File outputFile, byte[] buf) throws IOException {
216 OutputStream out = new FileOutputStream(outputFile);
217 int readBytes = source.read(buf);
218 while (readBytes != -1) {
219 out.write(buf, 0, readBytes);
220 readBytes = source.read(buf);
221 }
222 out.flush();
223 out.close();
224 }
225
226 protected String getTempDirectoryName() {
227 return kualiConfigurationService.getPropertyValueAsString(OLEConstants.TEMP_DIRECTORY_KEY);
228 }
229
230
231
232
233 public boolean isFileUserIdentifierProperlyFormatted(String fileUserIdentifier) {
234 if (fileUserIdentifier == null) {
235 return false;
236 }
237
238 for (int i = 0; i < fileUserIdentifier.length(); i++) {
239 char c = fileUserIdentifier.charAt(i);
240 if (!(Character.isLetterOrDigit(c))) {
241 return false;
242 }
243 }
244 return true;
245 }
246
247 public void setConfigurationService(ConfigurationService kualiConfigurationService) {
248 this.kualiConfigurationService = kualiConfigurationService;
249 }
250
251 protected void deleteTempFiles(Map<String, File> typeToTempFiles) {
252 for (File tempFile : typeToTempFiles.values()) {
253 if (tempFile.exists()) {
254 boolean deletionSuccessful = tempFile.delete();
255 if (!deletionSuccessful) {
256 LOG.error("Unable to delete file (possibly due to unclosed InputStream or Reader on the file): " + tempFile.getAbsolutePath());
257 }
258 }
259 }
260 }
261
262
263
264
265 @Override
266 public List<String> getRequiredDirectoryNames() {
267 return new ArrayList<String>(){{add(getTempDirectoryName());}};
268 }
269 }
270