package org.molgenis.data.importer.wizard; import org.apache.commons.lang3.StringUtils; import org.molgenis.data.DataService; import org.molgenis.data.FileRepositoryCollectionFactory; import org.molgenis.data.MolgenisDataException; import org.molgenis.data.RepositoryCollection; import org.molgenis.data.importer.EntitiesValidationReport; import org.molgenis.data.importer.ImportService; import org.molgenis.data.importer.ImportServiceFactory; import org.molgenis.data.meta.NameValidator; import org.molgenis.data.meta.model.Package; import org.molgenis.ui.wizard.AbstractWizardPage; import org.molgenis.ui.wizard.Wizard; import org.molgenis.util.FileExtensionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import static org.molgenis.data.meta.DefaultPackage.PACKAGE_DEFAULT; @Component public class OptionsWizardPage extends AbstractWizardPage { private static final long serialVersionUID = -2931051095557369343L; private static final Logger LOG = LoggerFactory.getLogger(OptionsWizardPage.class); private final transient FileRepositoryCollectionFactory fileRepositoryCollectionFactory; private final transient ImportServiceFactory importServiceFactory; private transient DataService dataService; @Autowired public OptionsWizardPage(FileRepositoryCollectionFactory fileRepositoryCollectionFactory, ImportServiceFactory importServiceFactory, DataService dataService) { this.fileRepositoryCollectionFactory = fileRepositoryCollectionFactory; this.importServiceFactory = importServiceFactory; this.dataService = dataService; } @Override public String getTitle() { return "Options"; } @Override public String handleRequest(HttpServletRequest request, BindingResult result, Wizard wizard) { ImportWizardUtil.validateImportWizard(wizard); ImportWizard importWizard = (ImportWizard) wizard; String entityImportOption = request.getParameter("entity_option"); importWizard.setEntityImportOption(entityImportOption); if (importWizard.getMustChangeEntityName()) { String userGivenName = request.getParameter("name"); if (StringUtils.isEmpty(userGivenName)) { result.addError(new ObjectError("wizard", "Please enter an entity name")); return null; } try { NameValidator.validateName(userGivenName); if (dataService.hasRepository(userGivenName)) { result.addError(new ObjectError("wizard", "An entity with this name already exists.")); return null; } } catch (MolgenisDataException e) { ImportWizardUtil.handleException(e, importWizard, result, LOG, entityImportOption); return null; } File tmpFile = importWizard.getFile(); String fileName = tmpFile.getName(); // FIXME: can this be done a bit cleaner? String extension = FileExtensionUtils.findExtensionFromPossibilities(fileName, fileRepositoryCollectionFactory.createFileRepositoryCollection(tmpFile).getFileNameExtensions()); File file = new File(tmpFile.getParent(), userGivenName + "." + extension); tmpFile.renameTo(file); importWizard.setFile(file); } try { return validateInput(importWizard.getFile(), importWizard, result); } catch (Exception e) { ImportWizardUtil.handleException(e, importWizard, result, LOG, entityImportOption); } return null; } private String validateInput(File file, ImportWizard wizard, BindingResult result) throws Exception { // decide what importer to use... RepositoryCollection source = fileRepositoryCollectionFactory.createFileRepositoryCollection(file); ImportService importService = importServiceFactory.getImportService(file, source); EntitiesValidationReport validationReport = importService.validateImport(file, source); wizard.setEntitiesImportable(validationReport.getSheetsImportable()); wizard.setFieldsDetected(validationReport.getFieldsImportable()); wizard.setFieldsRequired(validationReport.getFieldsRequired()); wizard.setFieldsAvailable(validationReport.getFieldsAvailable()); wizard.setFieldsUnknown(validationReport.getFieldsUnknown()); Set<String> allPackages = new HashSet<>(validationReport.getPackages()); for (Package p : dataService.getMeta().getPackages()) { allPackages.add(p.getName()); } List<String> entitiesInDefaultPackage = new ArrayList<>(); for (String entityName : validationReport.getSheetsImportable().keySet()) { if (validationReport.getSheetsImportable().get(entityName)) { if (isInDefaultPackage(entityName, allPackages)) entitiesInDefaultPackage.add(entityName); } } wizard.setEntitiesInDefaultPackage(entitiesInDefaultPackage); List<String> packages = new ArrayList<>(validationReport.getPackages()); packages.add(0, PACKAGE_DEFAULT); wizard.setPackages(packages); String msg = null; if (validationReport.valid()) { wizard.setFile(file); msg = "File is validated and can be imported."; } else { wizard.setValidationMessage( "File did not pass validation see results below. Please resolve the errors and try again."); } return msg; } private boolean isInDefaultPackage(String entityName, Set<String> packages) { for (String packageName : packages) { if (entityName.toLowerCase().startsWith(packageName.toLowerCase())) return false; } return true; } }