/**
*
*/
package net.frontlinesms.data.importexport;
import java.io.File;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Collection;
import org.apache.log4j.Logger;
import net.frontlinesms.FrontlineSMSConstants;
import net.frontlinesms.FrontlineUtils;
import net.frontlinesms.csv.CsvImporter;
import net.frontlinesms.csv.CsvParseException;
import net.frontlinesms.csv.CsvRowFormat;
import net.frontlinesms.csv.CsvUtils;
import net.frontlinesms.data.domain.FrontlineMessage;
import net.frontlinesms.data.domain.FrontlineMultimediaMessage;
import net.frontlinesms.data.domain.FrontlineMessage.Status;
import net.frontlinesms.data.domain.FrontlineMessage.Type;
import net.frontlinesms.data.importexport.MessageCsvImportReport.MessageCsvImportReportState;
import net.frontlinesms.data.repository.MessageDao;
import net.frontlinesms.ui.i18n.FileLanguageBundle;
import net.frontlinesms.ui.i18n.InternationalisationUtils;
import net.frontlinesms.ui.i18n.LanguageBundle;
/**
* @author aga
*
*/
public class MessageCsvImporter extends CsvImporter {
//> INSTANCE PROPERTIES
private final Logger LOG = FrontlineUtils.getLogger(this.getClass());
//> CONSTRUCTORS
public MessageCsvImporter(File importFile) throws CsvParseException {
super(importFile);
}
//> IMPORT METHODS
/**
* Import messages from a CSV file.
* @param importFile the file to import from
* @param messageDao
* @param rowFormat
* @throws IOException If there was a problem accessing the file
* @throws CsvParseException If there was a problem with the format of the file
*/
public MessageCsvImportReport importMessages(MessageDao messageDao, CsvRowFormat rowFormat) throws CsvParseException {
LOG.trace("ENTER");
int multimediaMessageCount = 0;
LanguageBundle usedLanguageBundle = null;
for(String[] lineValues : super.getRawValues()) {
String typeString = rowFormat.getOptionalValue(lineValues, CsvUtils.MARKER_MESSAGE_TYPE);
String status = rowFormat.getOptionalValue(lineValues, CsvUtils.MARKER_MESSAGE_STATUS);
Status statusType;
try {
statusType = Status.valueOf(status.toUpperCase());
} catch (IllegalArgumentException ex) {
return new MessageCsvImportReport(MessageCsvImportReportState.FAILURE);
}
String sender = rowFormat.getOptionalValue(lineValues, CsvUtils.MARKER_SENDER_NUMBER);
String recipient = rowFormat.getOptionalValue(lineValues, CsvUtils.MARKER_RECIPIENT_NUMBER);
String dateString = rowFormat.getOptionalValue(lineValues, CsvUtils.MARKER_MESSAGE_DATE);
String content = rowFormat.getOptionalValue(lineValues, CsvUtils.MARKER_MESSAGE_CONTENT);
long date;
try {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
ParsePosition pos = new ParsePosition(0);
date = formatter.parse(dateString, pos).getTime();
} catch (Exception e) {
date = System.currentTimeMillis(); // TODO is this really what we want to do with an ill-formatted date?
}
FrontlineMessage message;
// To avoid checking the language bandle used everytime, we store it
if (usedLanguageBundle == null) {
usedLanguageBundle = getUsedLanguageBundle(typeString);
}
Type type = getTypeFromString(typeString, usedLanguageBundle); // FIXME what if language bundle is still null??
//Status status = getStatusFromString(statusString);
if (FrontlineMultimediaMessage.appearsToBeToString(content)) {
// Then it's a multimedia message
message = FrontlineMultimediaMessage.createMessageFromContentString(content, false);
message.setDate(date);
message.setSenderMsisdn(sender);
message.setRecipientMsisdn(recipient);
++multimediaMessageCount;
} else {
if (type.equals(Type.OUTBOUND)) {
message = FrontlineMessage.createOutgoingMessage(date, sender, recipient, content);
} else {
message = FrontlineMessage.createIncomingMessage(date, sender, recipient, content);
}
}
message.setStatus(statusType);
messageDao.saveMessage(message);
}
LOG.trace("EXIT");
return new MessageCsvImportReport(multimediaMessageCount);
}
//> HELPER METHODS
//> STATIC HELPER METHODS
public static Type getTypeFromString(String typeString, LanguageBundle languageBundle) {
if (typeString.equalsIgnoreCase(InternationalisationUtils.getI18nString(FrontlineSMSConstants.COMMON_SENT, languageBundle))) {
return Type.OUTBOUND;
} else if (typeString.equalsIgnoreCase(InternationalisationUtils.getI18nString(FrontlineSMSConstants.COMMON_RECEIVED, languageBundle))) {
return Type.RECEIVED;
}
return Type.UNKNOWN;
}
/** Attempt to match the Language bundle used for message types to a particular language bundle */
public static LanguageBundle getUsedLanguageBundle(String typeString) {
Collection<FileLanguageBundle> languageBundles = InternationalisationUtils.getLanguageBundles();
for (FileLanguageBundle languageBundle : languageBundles) {
if (typeString.equalsIgnoreCase(InternationalisationUtils.getI18nString(FrontlineSMSConstants.COMMON_SENT, languageBundle))
|| typeString.equalsIgnoreCase(InternationalisationUtils.getI18nString(FrontlineSMSConstants.COMMON_RECEIVED, languageBundle))) {
return languageBundle;
}
}
return null;
}
}