package ca.intelliware.ihtsdo.mlds.service.affiliatesimport; import java.io.StringWriter; import javax.annotation.Resource; import org.apache.commons.lang.ClassUtils; import org.apache.commons.lang.StringUtils; import org.springframework.stereotype.Service; import ca.intelliware.ihtsdo.mlds.domain.Affiliate; import ca.intelliware.ihtsdo.mlds.domain.AffiliateDetails; import ca.intelliware.ihtsdo.mlds.domain.Application; import ca.intelliware.ihtsdo.mlds.domain.PrimaryApplication; import ca.intelliware.ihtsdo.mlds.repository.AffiliateRepository; import ca.intelliware.ihtsdo.mlds.service.affiliatesimport.AffiliatesImportSpec.ColumnSpec; import com.google.common.base.Objects; @Service public class AffiliatesExporterService extends BaseAffiliatesGenerator { public static final int EXAMPLE_DATA_ROWS = 2; @Resource AffiliateRepository affiliateRepository; @Resource AffiliatesImportGenerator affiliatesImportGenerator; public String exportToCSV() { StringWriter writer = new StringWriter(); writeHeader(writer); writeAffiliates(writer); return writer.toString(); } private void writeAffiliates(StringWriter writer) { for (Affiliate affiliate : affiliateRepository.findAll()) { writeAffiliate(writer, affiliate); } } private void writeAffiliate(StringWriter writer, Affiliate affiliate) { SeparatorWriter separatorWriter = new SeparatorWriter(); for (FieldMapping fieldMapping : affiliatesMapper.getMappings()) { separatorWriter.append(writer); Object rootObject = findRootObject(affiliate, fieldMapping); String stringValue = toStringValue(fieldMapping, rootObject); // Must have a value to allow re-import for affiliate added by users in our system. if (Objects.equal(fieldMapping.columnName, "importKey") && StringUtils.isBlank(stringValue)) { stringValue = generatePlaceHolderImportKey(affiliate.getAffiliateId()); } writer.append(stringValue); } appendLineEnding(writer); } private String toStringValue(FieldMapping fieldMapping, Object rootObject) { Object value = fieldMapping.accessor.getValue(rootObject); return fieldMapping.valueConverter.toString(value); } private Object findRootObject(Affiliate affiliate, FieldMapping fieldMapping) { if (fieldMapping.rootClazz.equals(Application.class) || fieldMapping.rootClazz.equals(PrimaryApplication.class)) { return affiliate.getApplication(); } else if (fieldMapping.rootClazz.equals(Affiliate.class)) { return affiliate; } else if (fieldMapping.rootClazz.equals(AffiliateDetails.class)) { return affiliate.getAffiliateDetails(); } return new IllegalStateException("Unsupported root class field mapping"); } public AffiliatesImportSpec exportSpec() { AffiliatesImportSpec spec = new AffiliatesImportSpec(); spec.example = affiliatesImportGenerator.generateFile(EXAMPLE_DATA_ROWS); for (FieldMapping fieldMapping : affiliatesMapper.getMappings()) { ColumnSpec columnSpec = generateColumnSpec(fieldMapping); spec.getColumns().add(columnSpec); } return spec; } private ColumnSpec generateColumnSpec(FieldMapping fieldMapping) { ColumnSpec columnSpec = new AffiliatesImportSpec.ColumnSpec(); columnSpec.attributeClass = ClassUtils.getShortClassName(fieldMapping.accessor.getAttributeClass()); columnSpec.columnName = fieldMapping.columnName; columnSpec.required = fieldMapping.required; columnSpec.example = getExampleValue(fieldMapping); columnSpec.options = fieldMapping.getOptions(); return columnSpec; } private String getExampleValue(FieldMapping fieldMapping) { return affiliatesImportGenerator.generateValue(fieldMapping, 0, new AffiliatesImportGenerator.GeneratorContext()); } }