/*
* 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.vnd.batch;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.kuali.kfs.sys.batch.BatchInputFileTypeBase;
import org.kuali.kfs.sys.exception.ParseException;
import org.kuali.kfs.vnd.VendorConstants;
import org.kuali.kfs.vnd.VendorKeyConstants;
import org.kuali.kfs.vnd.businessobject.DebarredVendorDetail;
import org.kuali.rice.core.api.datetime.DateTimeService;
import au.com.bytecode.opencsv.CSVReader;
public class VendorExcludeInputFileType extends BatchInputFileTypeBase{
private static final Logger LOG = Logger.getLogger(VendorExcludeInputFileType.class);
private static final String FILE_NAME_PREFIX = "epls_debarred_vendors_";
public static final int[] FIELD_SIZES = {200, 150, 50, 50, 20, 2, 20, 1000, 1000}; //Size limits for the fields
private String fileTypeIdentifier;
private DateTimeService dateTimeService;
/**
* @return the electronic invoice file type identifier
*/
@Override
public String getFileTypeIdentifer() {
return VendorConstants.VENDOR_EXCLUDE_FILE_TYPE_INDENTIFIER;
}
/**
* doesn't do any validation
* @see org.kuali.kfs.sys.batch.BatchInputFileType#validate(java.lang.Object)
*/
@Override
public boolean validate(Object parsedFileContents) {
return true;
}
/**
* @see org.kuali.kfs.sys.batch.BatchInputType#getTitleKey()
*/
@Override
public String getTitleKey() {
return VendorKeyConstants.MESSAGE_BATCH_UPLOAD_VENDOR_EXCLUDE;
}
/** @see org.kuali.kfs.sys.batch.BatchInputFileType#getAuthorPrincipalName(File)
*/
@Override
public String getAuthorPrincipalName(File file) {
return null;
}
/**
* @see org.kuali.kfs.sys.batch.BatchInputFileType#process(java.lang.String, java.lang.Object)
*/
@Override
public void process(String fileName, Object parsedFileContents) {
// does nothing
}
/**
* @param principalName - not used
* @param parsedFileContents List - not used
* @param fileUserIdentifier - not used
* @return file name prefix appended by current date
* @see org.kuali.kfs.sys.batch.BatchInputFileType#getFileName(String, Object, String)
*/
@Override
public String getFileName(String principalName, Object parsedFileContents, String fileUserIdentifuer) {
String fileName = FILE_NAME_PREFIX;
fileName += "_" + dateTimeService.toDateTimeStringForFilename(dateTimeService.getCurrentDate());
fileName = org.apache.commons.lang.StringUtils.remove(fileName, " ");
return fileName;
}
@Override
public Object parse(byte[] fileByteContent) throws ParseException {
LOG.info("Parsing Vendor Exclude Input File ...");
// create CSVReader, using conventional separator, quote, null escape char, skip first line, use strict quote, ignore leading white space
int skipLine = 1; // skip the first line, which is the header line
Reader inReader = new InputStreamReader(new ByteArrayInputStream(fileByteContent));
CSVReader reader = new CSVReader(inReader, ',', '"', Character.MIN_VALUE, skipLine, true, true);
List <DebarredVendorDetail> debarredVendors = new ArrayList<DebarredVendorDetail>();
String[] nextLine;
DebarredVendorDetail vendor;
int lineNumber = skipLine;
try {
while ((nextLine = reader.readNext()) != null) {
lineNumber++;
LOG.debug("Line " + lineNumber + ": " + nextLine[0]);
vendor = new DebarredVendorDetail();
boolean emptyLine = true;
// this should never happen, as for an empty line, CSVReader.readNext returns a string array with an empty string as the only element
// but just in case somehow a zero sized array is returned, we skip it.
if (nextLine.length == 0) {
continue;
}
StringBuffer name = new StringBuffer();
// if the name field is not empty, use that as vendor name
if (StringUtils.isNotEmpty(nextLine[0])) {
name.append(nextLine[0]);
}
// otherwise, there should be a first/middle/last name, which we concatenate into vendor name
else {
if (nextLine.length > 1 && !StringUtils.isNotEmpty(nextLine[1])) {
name.append(" " + nextLine[1]);
}
if (nextLine.length > 2 && !StringUtils.isNotEmpty(nextLine[2])) {
name.append(" " + nextLine[2]);
}
if (nextLine.length > 3 && !StringUtils.isNotEmpty(nextLine[3])) {
name.append(" " + nextLine[3]);
}
if (nextLine.length > 4 && !StringUtils.isNotEmpty(nextLine[4])) {
name.append(" " + nextLine[4]);
}
if (nextLine.length > 5 && StringUtils.isNotEmpty(nextLine[5])) {
name.append(" " + nextLine[5]);
}
}
if (StringUtils.isNotEmpty(name.toString())) {
vendor.setName(StringUtils.left(name.toString(), FIELD_SIZES[0]));
emptyLine = false;
}
if (nextLine.length > 6 && StringUtils.isNotEmpty(nextLine[6])) {
vendor.setAddress1(StringUtils.left(nextLine[6], FIELD_SIZES[1]));
emptyLine = false;
}
if (nextLine.length > 7 && StringUtils.isNotEmpty(nextLine[7])) {
vendor.setAddress2(StringUtils.left(nextLine[7], FIELD_SIZES[2]));
emptyLine = false;
}
if (nextLine.length > 8 && StringUtils.isNotEmpty(nextLine[8])) {
vendor.setCity(StringUtils.left(nextLine[8], FIELD_SIZES[3]));
emptyLine = false;
}
if (nextLine.length > 9 && StringUtils.isNotEmpty(nextLine[9])) {
vendor.setProvince(StringUtils.left(nextLine[9], FIELD_SIZES[4]));
emptyLine = false;
}
if (nextLine.length > 10 && StringUtils.isNotEmpty(nextLine[10])) {
vendor.setState(StringUtils.left(nextLine[10], FIELD_SIZES[5]));
emptyLine = false;
}
if (nextLine.length > 11 && StringUtils.isNotEmpty(nextLine[11])) {
vendor.setZip(StringUtils.left(nextLine[11], FIELD_SIZES[6]));
emptyLine = false;
}
if (nextLine.length > 13 && StringUtils.isNotEmpty(nextLine[13])) {
vendor.setAliases(StringUtils.left(StringUtils.remove(nextLine[13], "\""), FIELD_SIZES[7]));
emptyLine = false;
}
if (nextLine.length > 18 && StringUtils.isNotEmpty(nextLine[18])) {
vendor.setDescription(StringUtils.left(nextLine[18], FIELD_SIZES[8]));
emptyLine = false;
}
if (emptyLine) {
/* give warnings on a line that doesn't have any useful vendor info
LOG.warn("Note: line " + lineNumber + " in the Vendor Exclude Input File is skipped since all parsed fields are empty.");
*/
// throw parser exception on a line that doesn't have any useful vendor info.
// Since the file usually doesn't contain empty lines or lines with empty fields, this happening usually is a good indicator that
// some line ahead has wrong data format, for ex, missing a quote on a field, which could mess up the following fields and lines.
throw new ParseException("Line " + lineNumber + " in the Vendor Exclude Input File contains no valid field or only empty fields within quote pairs. Please check the lines ahead to see if any field is missing quotes.");
}
else {
vendor.setLoadDate(new Date(new java.util.Date().getTime()));
debarredVendors.add(vendor);
}
}
}
catch (IOException ex) {
throw new ParseException("Error reading Vendor Exclude Input File at line " + lineNumber + ": " + ex.getMessage());
}
LOG.info("Total number of lines read from Vendor Exclude Input File: " + lineNumber);
LOG.info("Total number of vendors parsed from Vendor Exclude Input File: " + debarredVendors.size());
return debarredVendors;
}
/**
* Gets the fileTypeIdentifier attribute.
* @return Returns the fileTypeIdentifier.
*/
public String getFileTypeIdentifier() {
return fileTypeIdentifier;
}
/**
* Sets the fileTypeIdentifier attribute value.
* @param fileTypeIdentifier The fileTypeIdentifier to set.
*/
public void setFileTypeIdentifier(String fileTypeIdentifier) {
this.fileTypeIdentifier = fileTypeIdentifier;
}
/**
* Gets the dateTimeService attribute.
* @return Returns the dateTimeService.
*/
public DateTimeService getDateTimeService() {
return dateTimeService;
}
/**
* Sets the dateTimeService attribute value.
* @param dateTimeService The dateTimeService to set.
*/
public void setDateTimeService(DateTimeService dateTimeService) {
this.dateTimeService = dateTimeService;
}
}