/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.sys.batch;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStreamReader;
import org.apache.log4j.Logger;
import org.kuali.kfs.gl.service.impl.StringHelper;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.exception.ParseException;
import org.kuali.rice.core.api.datetime.DateTimeService;
/**
* Implementation of BatchInputFileType which parses flat files
*/
public class FlatFileParserBase extends BatchInputFileTypeBase {
protected static Logger LOG = Logger.getLogger(FlatFileParserBase.class);
protected FlatFileSpecification flatFileSpecification;
protected String fileNamePrefix;
protected DateTimeService dateTimeService;
protected String fileTypeIdentifier;
protected String titleKey;
protected FlatFileDataHandler processor;
/**
* Returns the name of an uploaded file
*/
@Override
public String getFileName(String principalName, Object parsedFileContents, String fileUserIdentifier) {
String fileName = processor.getFileName(principalName, parsedFileContents, fileUserIdentifier);
if(StringHelper.isNullOrEmpty(fileName)) {
fileName = getFileNamePrefix();
fileName += principalName;
if (org.apache.commons.lang.StringUtils.isNotBlank(fileUserIdentifier)) {
fileName += "_" + fileUserIdentifier;
}
fileName += "_" + dateTimeService.toDateTimeStringForFilename(dateTimeService.getCurrentDate());
// remove spaces in filename
fileName = org.apache.commons.lang.StringUtils.remove(fileName, " ");
}
return fileName;
}
/**
* All foundation developers are brilliant at spelling!
*
* @param fileTypeIdentifier the file identifier to set
*/
public void setFileTypeIdentifer(String fileTypeIdentifier) {
this.fileTypeIdentifier = fileTypeIdentifier;
}
/**
* The correctly spelled setter name - just to avoid injection confusion
*
* @param fileTypeIdentifier the file type identifier
*/
public void setFileTypeIdentifier(String fileTypeIdentifier) {
this.fileTypeIdentifier = fileTypeIdentifier;
}
/**
* Sets the key of the message to show in the title bar of the upload page for this file
* @param titleKey
*/
public void setTitleKey(String titleKey) {
this.titleKey = titleKey;
}
/**
* @return a FlatFileDataValidator associated with this instance of the FixedWidthFlatFileParserBase
*/
public FlatFileDataHandler getProcessor() {
return processor;
}
/**
* Sets the processor which will validate and process the file once all flat file data has been parsed
* @param processor the implementation of FlatFileDataHandler to utilize
*/
public void setProcessor(FlatFileDataHandler processor) {
this.processor = processor;
}
/**
* Reads each line of the flat file and uses the injected FlatFileSpecification to parse into an object graph
* @param fileByteContent the contents file to parse
* @return an object graph of parsed objects
* @see org.kuali.kfs.sys.batch.BatchInputFileType#parse(byte[])
*/
@Override
public Object parse(byte[] fileByteContent) throws ParseException {
BufferedReader bufferedFileReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(fileByteContent)));
String lineToParse;
Object returnObject = null;
FlatFileParseTracker tracker = SpringContext.getBean(FlatFileParseTracker.class);
tracker.initialize(flatFileSpecification);
int lineNumber = 1;
try {
while ((lineToParse = bufferedFileReader.readLine()) != null) {
Object parseIntoObject = tracker.getObjectToParseInto(lineToParse);
if (parseIntoObject != null) {
FlatFileObjectSpecification parseSpecification = flatFileSpecification.getObjectSpecification(parseIntoObject.getClass());
if (parseSpecification.getParseProperties() != null && !parseSpecification.getParseProperties().isEmpty()) {
flatFileSpecification.parseLineIntoObject(parseSpecification, lineToParse, parseIntoObject, lineNumber);
tracker.completeLineParse();
}
}
lineNumber++;
}
returnObject = tracker.getParsedObjects();
}
catch (Exception e) {
LOG.error(e.getMessage() + " happend in parsing file content ", e);
throw new ParseException(e.getMessage());
}
return returnObject;
}
/**
* Calls the processor if it is available
*/
@Override
public void process(String fileName, Object parsedFileContents) {
if (getProcessor() != null) {
getProcessor().process(fileName, parsedFileContents);
}
}
/**
* @return currently always returns true; do we want to extend that sometime?
*/
@Override
public boolean validate(Object parsedFileContents) {
if (getProcessor() == null) {
return true;
}
return getProcessor().validate(parsedFileContents);
}
/**
* Sets the FlatFileSpecification that instructs how to carry out the parse
* @param flatFileClassIdentifier the FlatFileSpecification that instructs how to carry out the parse
*/
public void setFlatFileSpecification(AbstractFlatFileSpecificationBase flatFileClassIdentifier) {
this.flatFileSpecification = flatFileClassIdentifier;
}
/**
* Sets the prefix of the file name which this parser reads
* @param fileNamePrefix
*/
public void setFileNamePrefix(String fileNamePrefix) {
this.fileNamePrefix = fileNamePrefix;
}
/**
* Sets an implementation of the DateTimeService for use in parsing
* @param dateTimeService
*/
public void setDateTimeService(DateTimeService dateTimeService) {
this.dateTimeService = dateTimeService;
}
/**
* Determines the principal name of the author of a file from the file name
* @param file the file to determine the author of
* @return the principal name of the author
*/
@Override
public String getAuthorPrincipalName(File file) {
return org.apache.commons.lang.StringUtils.substringBetween(file.getName(), getFileNamePrefix(), "_");
}
/**
* @return the identifier for flat files of this type
*/
@Override
public String getFileTypeIdentifer() {
return fileTypeIdentifier;
}
/**
* @return the prefix of the name of flat files of this type
*/
public String getFileNamePrefix() {
return fileNamePrefix;
}
/**
* @return the key of the message to be used as the title of the upload screen of this file type
*/
@Override
public String getTitleKey() {
return titleKey;
}
}