View Javadoc
1   package org.kuali.ole.sys.batch;
2   
3   import java.io.BufferedReader;
4   import java.io.ByteArrayInputStream;
5   import java.io.File;
6   import java.io.InputStreamReader;
7   
8   import org.apache.log4j.Logger;
9   import org.kuali.ole.gl.service.impl.StringHelper;
10  import org.kuali.ole.sys.context.SpringContext;
11  import org.kuali.ole.sys.exception.ParseException;
12  import org.kuali.rice.core.api.datetime.DateTimeService;
13  
14  /**
15   * Implementation of BatchInputFileType which parses flat files
16   */
17  public class FlatFileParserBase extends BatchInputFileTypeBase {
18      protected static Logger LOG = Logger.getLogger(FlatFileParserBase.class);
19      protected FlatFileSpecification flatFileSpecification;
20      protected String fileNamePrefix;
21      protected DateTimeService dateTimeService;
22      protected String fileTypeIdentifier;
23      protected String titleKey;
24      protected FlatFileDataHandler processor;
25  
26      /**
27       * Returns the name of an uploaded file
28       */
29      @Override
30      public String getFileName(String principalName, Object parsedFileContents, String fileUserIdentifier) {
31          String fileName = processor.getFileName(principalName, parsedFileContents, fileUserIdentifier);
32          if(StringHelper.isNullOrEmpty(fileName)) {
33              fileName = getFileNamePrefix();
34              fileName += principalName;
35              if (org.apache.commons.lang.StringUtils.isNotBlank(fileUserIdentifier)) {
36                  fileName += "_" + fileUserIdentifier;
37              }
38              fileName += "_" + dateTimeService.toDateTimeStringForFilename(dateTimeService.getCurrentDate());
39  
40              // remove spaces in filename
41              fileName = org.apache.commons.lang.StringUtils.remove(fileName, " ");
42          }
43          return fileName;
44      }
45  
46      /**
47       * All foundation developers are brilliant at spelling!
48       *
49       * @param fileTypeIdentifier the file identifier to set
50       */
51      public void setFileTypeIdentifer(String fileTypeIdentifier) {
52          this.fileTypeIdentifier = fileTypeIdentifier;
53      }
54  
55      /**
56       * The correctly spelled setter name - just to avoid injection confusion
57       *
58       * @param fileTypeIdentifier the file type identifier
59       */
60      public void setFileTypeIdentifier(String fileTypeIdentifier) {
61          this.fileTypeIdentifier = fileTypeIdentifier;
62      }
63  
64      /**
65       * Sets the key of the message to show in the title bar of the upload page for this file
66       * @param titleKey
67       */
68      public void setTitleKey(String titleKey) {
69          this.titleKey = titleKey;
70      }
71  
72      /**
73       * @return a FlatFileDataValidator associated with this instance of the FixedWidthFlatFileParserBase
74       */
75      public FlatFileDataHandler getProcessor() {
76          return processor;
77      }
78  
79      /**
80       * Sets the processor which will validate and process the file once all flat file data has been parsed
81       * @param processor the implementation of FlatFileDataHandler to utilize
82       */
83      public void setProcessor(FlatFileDataHandler processor) {
84          this.processor = processor;
85      }
86  
87      /**
88       * Reads each line of the flat file and uses the injected FlatFileSpecification to parse into an object graph
89       * @param fileByteContent the contents file to parse
90       * @return an object graph of parsed objects
91       * @see org.kuali.ole.sys.batch.BatchInputFileType#parse(byte[])
92       */
93      @Override
94      public Object parse(byte[] fileByteContent) throws ParseException {
95          BufferedReader bufferedFileReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(fileByteContent)));
96          String lineToParse;
97          Object returnObject = null;
98          FlatFileParseTracker tracker = SpringContext.getBean(FlatFileParseTracker.class);
99          tracker.initialize(flatFileSpecification);
100         int  lineNumber = 1;
101         try {
102             while ((lineToParse = bufferedFileReader.readLine()) != null) {
103                 Object parseIntoObject = tracker.getObjectToParseInto(lineToParse);
104 
105                 if (parseIntoObject != null) {
106                     FlatFileObjectSpecification parseSpecification = flatFileSpecification.getObjectSpecification(parseIntoObject.getClass());
107 
108                     if (parseSpecification.getParseProperties() != null && !parseSpecification.getParseProperties().isEmpty()) {
109                         flatFileSpecification.parseLineIntoObject(parseSpecification, lineToParse, parseIntoObject, lineNumber);
110                         tracker.completeLineParse();
111                     }
112                 }
113                lineNumber++;
114             }
115             returnObject = tracker.getParsedObjects();
116 
117 
118         }
119         catch (Exception e) {
120             LOG.error(e.getMessage() + " happend in parsing file content ", e);
121             throw new ParseException(e.getMessage());
122         }
123 
124         return returnObject;
125     }
126 
127     /**
128      * Calls the processor if it is available
129      */
130     @Override
131     public void process(String fileName, Object parsedFileContents) {
132         if (getProcessor() != null)
133             getProcessor().process(fileName, parsedFileContents);
134     }
135 
136     /**
137      * @return currently always returns true; do we want to extend that sometime?
138      */
139     @Override
140     public boolean validate(Object parsedFileContents) {
141         if (getProcessor() == null)
142             return true;
143         return getProcessor().validate(parsedFileContents);
144     }
145 
146     /**
147      * Sets the FlatFileSpecification that instructs how to carry out the parse
148      * @param flatFileClassIdentifier the FlatFileSpecification that instructs how to carry out the parse
149      */
150     public void setFlatFileSpecification(AbstractFlatFileSpecificationBase flatFileClassIdentifier) {
151         this.flatFileSpecification = flatFileClassIdentifier;
152     }
153 
154     /**
155      * Sets the prefix of the file name which this parser reads
156      * @param fileNamePrefix
157      */
158     public void setFileNamePrefix(String fileNamePrefix) {
159         this.fileNamePrefix = fileNamePrefix;
160     }
161 
162     /**
163      * Sets an implementation of the DateTimeService for use in parsing
164      * @param dateTimeService
165      */
166     public void setDateTimeService(DateTimeService dateTimeService) {
167         this.dateTimeService = dateTimeService;
168     }
169 
170     /**
171      * Determines the principal name of the author of a file from the file name
172      * @param file the file to determine the author of
173      * @return the principal name of the author
174      */
175     @Override
176     public String getAuthorPrincipalName(File file) {
177         return org.apache.commons.lang.StringUtils.substringBetween(file.getName(), getFileNamePrefix(), "_");
178     }
179 
180     /**
181      * @return the identifier for flat files of this type
182      */
183     @Override
184     public String getFileTypeIdentifer() {
185         return fileTypeIdentifier;
186     }
187 
188     /**
189      * @return the prefix of the name of flat files of this type
190      */
191     public String getFileNamePrefix() {
192         return fileNamePrefix;
193     }
194 
195     /**
196      * @return the key of the message to be used as the title of the upload screen of this file type
197      */
198     @Override
199     public String getTitleKey() {
200         return titleKey;
201     }
202 }