package ca.intelliware.ihtsdo.mlds.service.affiliatesimport;
import java.io.StringWriter;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.springframework.stereotype.Service;
import com.google.common.base.Objects;
/**
* Generate a valid affiliates import file with a specified number of rows.
*/
@Service
public class AffiliatesImportGenerator extends BaseAffiliatesGenerator {
public String generateFile(int rows) {
GeneratorContext context = new GeneratorContext();
context.rows = rows;
return generateFile(context);
}
public String generateFile(GeneratorContext context) {
StringWriter writer = new StringWriter();
writeHeader(writer);
writeAffiliates(writer, context);
return writer.toString();
}
private void writeAffiliates(StringWriter writer, GeneratorContext context) {
for (int i = 0; i < context.rows; i++) {
writeAffiliate(writer, i, context);
}
}
private void writeAffiliate(StringWriter writer, int i, GeneratorContext context) {
SeparatorWriter separatorWriter = new SeparatorWriter();
for (FieldMapping fieldMapping : affiliatesMapper.getMappings()) {
separatorWriter.append(writer);
String stringValue = generateValue(fieldMapping, i, context);
writer.append(stringValue);
}
appendLineEnding(writer);
}
public String generateValue(FieldMapping fieldMapping, int i, GeneratorContext context) {
String stringValue = generateBasicValue(fieldMapping, i);
if (Objects.equal(fieldMapping.columnName, "importKey")) {
// Must have a value to allow re-import for affiliate added by users in our system.
stringValue = context.getBaseKey()+i;
} else if (Objects.equal(fieldMapping.columnName, "member")) {
stringValue = context.getSourceMemberKey();
} else if (Objects.equal(fieldMapping.columnName, "addressCountry")) {
stringValue = context.getSourceCountryKey();
} else if (StringUtils.containsIgnoreCase(fieldMapping.columnName, "email")) {
stringValue = generateEmail(fieldMapping, i, context);
} else if (StringUtils.containsIgnoreCase(fieldMapping.columnName, "street")) {
stringValue = generateStreet(fieldMapping, i, context);
} else if (StringUtils.containsIgnoreCase(fieldMapping.columnName, "city")) {
stringValue = generateCity(fieldMapping, i, context);
} else if (StringUtils.containsIgnoreCase(fieldMapping.columnName, "post")) {
stringValue = generatePostCode(fieldMapping, i, context);
} else if (StringUtils.containsIgnoreCase(fieldMapping.columnName, "number")) {
stringValue = generateTelephoneNumber(fieldMapping, i, context);
} else if (StringUtils.containsIgnoreCase(fieldMapping.columnName, "extension")) {
stringValue = generateExtensionNumber(fieldMapping, i, context);
} else if (StringUtils.containsIgnoreCase(fieldMapping.columnName, "first")) {
stringValue = generateFirstName(fieldMapping, i, context);
} else if (StringUtils.containsIgnoreCase(fieldMapping.columnName, "last")) {
stringValue = generateLastName(fieldMapping, i, context);
}
return stringValue;
}
private String generateBasicValue(FieldMapping fieldMapping, int hint) {
List<String> options = fieldMapping.getOptions();
if (options.size() > 0) {
return options.get(hint % options.size());
} else {
String[] words = StringUtils.splitByCharacterTypeCamelCase(fieldMapping.columnName);
String capitalizedExample = WordUtils.capitalizeFully("Example "+StringUtils.join(words, " "));
if (hint > 0) {
capitalizedExample += " "+hint;
}
return capitalizedExample;
}
}
private String generateExtensionNumber(FieldMapping fieldMapping, int i, GeneratorContext context) {
return StringUtils.leftPad(Integer.toString(hashOfColumnName(fieldMapping)%1000), 3, '0');
}
private String generateStreet(FieldMapping fieldMapping, int i, GeneratorContext context) {
return Integer.toString(i)+ " "+ (WordUtils.capitalizeFully(StringUtils.join(StringUtils.splitByCharacterTypeCamelCase(fieldMapping.columnName), " ")));
}
private String generateCity(FieldMapping fieldMapping, int i, GeneratorContext context) {
//From http://en.wikipedia.org/wiki/List_of_most_popular_given_names
// size 11
return generateNameFromList(i, new String[] {"Skagen", "Jerup", "Strandby", "Sindal", "Bindslev", "Frederikshavn", "Ranum", "Aars", "Hadsund", "Mariager", "Copenhagen"});
}
private String generateFirstName(FieldMapping fieldMapping, int i, GeneratorContext context) {
//From http://en.wikipedia.org/wiki/List_of_most_popular_given_names
// size 9
return generateNameFromList(i, new String[] {"William", "Lucas", "Victor", "Noah", "Sofia", "Ida", "Isabella", "Emma", "Freja"});
}
private String generateLastName(FieldMapping fieldMapping, int i, GeneratorContext context) {
//From http://en.wikipedia.org/wiki/List_of_most_common_surnames_in_Europe
// size 10 -- keep list sizes relatively-prime so we get good mixing for search testing.
return generateNameFromList(i, new String[] {"Jensen", "Nielsen", "Hansen", "Pedersen", "Andersen", "Christensen", "Larsen", "S\u00F8rensen", "Rasmussen", "J\u00F8rgensen"})
+ appendUniquenessHint(i);
}
private String appendUniquenessHint(int hint) {
return appendUniquenessHint(hint, " ");
}
private String appendUniquenessHint(int hint, String separator) {
return hint > 0 ? separator+hint : "";
}
private String generateNameFromList(int i, String[] options) {
return options[i%options.length];
}
private String generatePostCode(FieldMapping fieldMapping, int i, GeneratorContext context) {
return Integer.toString(9000 + hashOfColumnName(fieldMapping)%1000);
}
private String generateTelephoneNumber(FieldMapping fieldMapping, int i, GeneratorContext context) {
return "+1 416 "+StringUtils.leftPad(Integer.toString(hashOfColumnName(fieldMapping)%1000), 3, '0')+" "+StringUtils.leftPad(Integer.toString(i), 4, '0');
}
private int hashOfColumnName(FieldMapping fieldMapping) {
// Work around Math.abs() broken behaviour for Integer.MIN_VALUE
// http://findbugs.blogspot.ca/2006/09/is-mathabs-broken.html
return fieldMapping.columnName.hashCode() & Integer.MAX_VALUE;
}
private String generateEmail(FieldMapping fieldMapping, int i, GeneratorContext context) {
return fieldMapping.columnName+appendUniquenessHint(i, "+")+"@email.com";
}
public static class GeneratorContext {
private int rows = 1;
private String baseKey = "AFFILIATE-";
private String sourceMemberKey = "DK";
private String sourceCountryKey = "DK";
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public String getBaseKey() {
return baseKey;
}
public void setBaseKey(String baseKey) {
this.baseKey = baseKey;
}
public String getSourceMemberKey() {
return sourceMemberKey;
}
public void setSourceMemberKey(String sourceMemberKey) {
this.sourceMemberKey = sourceMemberKey;
}
public String getSourceCountryKey() {
return sourceCountryKey;
}
public void setSourceCountryKey(String sourceCountryKey) {
this.sourceCountryKey = sourceCountryKey;
}
}
}