Java tutorial
/******************************************************************************* * Educational Online Test Delivery System * Copyright (c) 2013 American Institutes for Research * * Distributed under the AIR Open Source License, Version 1.0 * See accompanying file AIR-License-1_0.txt or at * http://www.smarterapp.org/documents/American_Institutes_for_Research_Open_Source_Software_License.pdf ******************************************************************************/ package org.opentestsystem.delivery.testreg.upload; import static org.apache.commons.beanutils.ConstructorUtils.invokeConstructor; import static org.apache.commons.lang.ClassUtils.isAssignable; import static org.apache.commons.lang.ClassUtils.isInnerClass; import static org.opentestsystem.delivery.testreg.rest.FileType.TXT; import static org.opentestsystem.delivery.testreg.rest.FileType.XLSX; import static org.opentestsystem.delivery.testreg.upload.parser.ParserTextUtils.trimTextValues; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import javax.annotation.Resource; import org.apache.commons.io.FilenameUtils; import org.opentestsystem.delivery.testreg.domain.ARTHelpers; import org.opentestsystem.delivery.testreg.domain.AccommodationResourceType; import org.opentestsystem.delivery.testreg.domain.Action; import org.opentestsystem.delivery.testreg.domain.FileUploadSummary; import org.opentestsystem.delivery.testreg.domain.FormatType; import org.opentestsystem.delivery.testreg.domain.Student; import org.opentestsystem.delivery.testreg.domain.TestRegistrationBase; import org.opentestsystem.delivery.testreg.domain.TestRegistrationBuilder; import org.opentestsystem.delivery.testreg.persistence.ParentEntityClassFinder; import org.opentestsystem.delivery.testreg.rest.FileType; import org.opentestsystem.delivery.testreg.service.MasterResourceAccommodationService; import org.opentestsystem.delivery.testreg.service.StudentService; import org.opentestsystem.delivery.testreg.service.TestRegPersister; import org.opentestsystem.delivery.testreg.upload.parser.ParserResult; import org.opentestsystem.delivery.testreg.upload.parser.UploadFileParser; import org.opentestsystem.shared.exception.LocalizedException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; // TODO Many of these methods are marked to throw Exception. Can we come up with a better Exception to throw? public class FileUploadUtils { @Autowired ParentEntityClassFinder parentEntityClassFinder; @Autowired MasterResourceAccommodationService masterResourceAccommodationService; @Autowired private StudentService studentService; @Resource(name = "entityBasedParserMap") Map<FileType, UploadFileParser<Map<FormatType, List<TestRegistrationBase>>>> entityBasedParserMap; public ParserResult<Map<FormatType, List<TestRegistrationBase>>> extractFile(final String fileName, final InputStream uploadFile, final String formatType) throws Exception { final String extension = FilenameUtils.getExtension(fileName); if (extension == null) { throw createNullExtensionException(extension); } switch (FileType.findByFilename(fileName)) { case XLS: case XLSX: return parseExcelFile(XLSX, formatType, uploadFile); case CSV: case TXT: return parseCSVFiles(TXT, formatType, uploadFile); default: throw createFileExtensionException("File extension must be either XLS or XLSX or CSV or TXT"); } } public ParserResult<Map<FormatType, List<TestRegistrationBase>>> parseExcelFile(final FileType type, final String formatType, final InputStream uploadFile) throws Exception { return this.entityBasedParserMap.get(type).parse(uploadFile, formatType); } public List<TestRegistrationBase> entityType(final FormatType formatType, final List<TestRegistrationBase> excelRows, final Object[] cellData) throws Exception { excelRows.add(getDomainObject(formatType, trimTextValues(cellData))); return excelRows; } public int entityAccommodationType(final Object[] cellData) throws Exception { return getDomainObject(trimTextValues(cellData)); } public int getDomainObject(final Object[] cellData) { //getting each row data during file-upload process and construct LinkedHashMap assign data to its corresponding key int counter = 0; List<String> headersList = masterResourceAccommodationService.getAllOptionsCodes(); HashMap<String, String> headerResourceTypes = masterResourceAccommodationService.getAllResourceTypes(); headerResourceTypes.put("StudentId", "SingleSelectResource"); headerResourceTypes.put("StateAbbreviation", "SingleSelectResource"); headerResourceTypes.put("Subject", "SingleSelectResource"); Map<String, String> accommodationMap = new LinkedHashMap<String, String>(); Map<String, Object> accommoMap = new LinkedHashMap<String, Object>(); if (cellData.length == 4) { accommoMap = convertDataToMap(cellData, headersList, headerResourceTypes); } else { for (int i = 0; i < headersList.size(); i++) { String key = ARTHelpers.convertCodeToUpperCase(headersList.get(i)); if (headerResourceTypes.containsKey(key) && headerResourceTypes.get(key) .equals(AccommodationResourceType.MultiSelectResource.name())) { List<String> al = new ArrayList<String>(); StringTokenizer tokenizer = new StringTokenizer(cellData[i].toString(), ";"); while (tokenizer.hasMoreElements()) { String token = (String) tokenizer.nextElement(); al.add(token.trim()); } accommodationMap.put(headersList.get(i), al.toString()); accommoMap.put(headersList.get(i), al); } else if (headerResourceTypes.containsKey(key) && headerResourceTypes.get(key) .equals(AccommodationResourceType.SingleSelectResource.name()) || headerResourceTypes.get(key).equals(AccommodationResourceType.EditResource.name())) { if (headersList.get(i).equalsIgnoreCase("subject") || headersList.get(i).equalsIgnoreCase("stateAbbreviation")) { accommodationMap.put(headersList.get(i), cellData[i].toString().toUpperCase()); accommoMap.put(headersList.get(i), cellData[i].toString().toUpperCase()); } else { accommodationMap.put(headersList.get(i), cellData[i].toString()); accommoMap.put(headersList.get(i), cellData[i].toString()); } } } } String studentId = (String) accommoMap.get("studentId"); String stateAbbreviation = (String) accommoMap.get("stateAbbreviation"); //saving accommodationMap we constructed into it's corresponding student based on studentId,stateAbbreviation Student student = studentService.saveAccommodation(studentId, stateAbbreviation, accommoMap); if (student != null) { counter++; } return counter; } /** * Converting accommodationData( accommodation upload data ) to accommodationMap * * @param columns accommodation data from upload file * @param headers list of all accommodation resource codes * @param headerResourceTypes masterResourceAccommodation map with key : resourceCode and value : resourceType * @return map with data( values ) assigned to its corresponding resource codes(key) */ @SuppressWarnings("unchecked") private Map<String, Object> convertDataToMap(Object[] columns, List<String> headers, HashMap<String, String> headerResourceTypes) { HashMap<String, Object> accommodationMap = new LinkedHashMap<String, Object>(); HashMap<String, Object> data = new LinkedHashMap<String, Object>(); for (String columnHeader : headers) { if (columnHeader.equalsIgnoreCase("subject") || columnHeader.equalsIgnoreCase("stateAbbreviation")) { accommodationMap.put(columnHeader, columns[headers.indexOf(columnHeader)].toString().toUpperCase()); } else if (columnHeader.equalsIgnoreCase("studentId")) { accommodationMap.put(columnHeader, columns[headers.indexOf(columnHeader)].toString()); } } String allAccommodationCodes = columns[3].toString(); List<String> accommodationCode = new ArrayList<String>(); StringTokenizer tokenizer = new StringTokenizer(allAccommodationCodes, "|"); while (tokenizer.hasMoreElements()) { String token = (String) tokenizer.nextElement(); accommodationCode.add(token.trim()); } HashMap<String, List<String>> masterAccommodationOptions = masterResourceAccommodationService .getMasterResourceOptions(); Set<String> masterCodes = masterAccommodationOptions.keySet(); for (String uploadCode : accommodationCode) { for (String resourceCode : masterCodes) { ArrayList<String> options = new ArrayList<String>(); if (uploadCode.contains("(") && uploadCode.contains(")")) { int startIndex = (uploadCode.indexOf("(")) + 1; int endIndex = (uploadCode.indexOf(")")); String editResource = uploadCode.substring(startIndex, endIndex); String matchResource = uploadCode.substring(0, uploadCode.indexOf("(")); if (resourceCode.equalsIgnoreCase(matchResource)) { data.put(resourceCode, editResource); break; } } else { if (masterAccommodationOptions.get(resourceCode).contains(uploadCode)) { String key = ARTHelpers.convertCodeToUpperCase(resourceCode); if (headerResourceTypes.containsKey(key) && headerResourceTypes.get(key) .equals(AccommodationResourceType.MultiSelectResource.name())) { if (data.containsKey(resourceCode)) { ArrayList<String> tempResourceCodes = (ArrayList<String>) data.get(resourceCode); if (tempResourceCodes != null) { tempResourceCodes.add(uploadCode); data.put(resourceCode, tempResourceCodes); break; } } else { options.add(uploadCode); data.put(resourceCode, options); break; } } else { data.put(resourceCode, uploadCode); break; } } } } } for (String resourceCode : masterAccommodationOptions.keySet()) { Set<String> accommodationResourceCodes = data.keySet(); if (accommodationResourceCodes.contains(resourceCode)) { String key = ARTHelpers.convertToLowerCase(resourceCode); accommodationMap.put(key, data.get(resourceCode)); } else { if (headerResourceTypes.containsKey(resourceCode) && headerResourceTypes.get(resourceCode) .equals(AccommodationResourceType.MultiSelectResource.name())) { ArrayList<String> accommoList = new ArrayList<String>(); accommodationMap.put(ARTHelpers.convertToLowerCase(resourceCode), accommoList); } else { accommodationMap.put(ARTHelpers.convertToLowerCase(resourceCode), ""); } } } return accommodationMap; } public TestRegistrationBase getDomainObject(final FormatType formatType, final Object[] cellData) { final Class<? extends TestRegistrationBase> sb11EntityClass = this.parentEntityClassFinder .getParentClass(formatType.name()); final Class<?>[] cArray = sb11EntityClass.getDeclaredClasses(); for (final Class<?> clazz : cArray) { if (isInnerClass(clazz) && isAssignable(clazz, TestRegistrationBuilder.class)) {// Builders as Static Inner class try { return (TestRegistrationBase) TestRegistrationBuilder.class .cast(invokeConstructor(clazz, new Object[] { cellData })).build(); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) { throw createInvalidTypeException(formatType.toString()); } } } throw createInvalidTypeException(formatType.toString()); } public TestRegistrationBase getDomainObject(final FormatType formatType, final FileDataRecord dataRecord) { return getDomainObject(formatType, dataRecord.getColumns()); } private ParserResult<Map<FormatType, List<TestRegistrationBase>>> parseCSVFiles(final FileType fileType, final String formatType, final InputStream uploadFile) throws Exception { return this.entityBasedParserMap.get(fileType).parse(uploadFile, formatType); } public FileUploadSummary processGroupEntities(final List<TestRegistrationBase> testRegEntities, final TestRegPersister entityService) { final FileUploadSummary summaryResponse = new FileUploadSummary(); final List<TestRegistrationBase> addEntityList = new ArrayList<>(); final List<TestRegistrationBase> updateEntityList = new ArrayList<>(); final List<TestRegistrationBase> deleteEntityList = new ArrayList<>(); for (final TestRegistrationBase entityObj : testRegEntities) { final Action action = entityObj.getAction(); switch (action) { case ADD: addEntityList.add(entityObj); break; case UPD: updateEntityList.add(entityObj); break; case DEL: deleteEntityList.add(entityObj); break; default: updateEntityList.add(entityObj); break; // add and upd will no longer be valid. we will always do an upsert // for now, this will look like an update } } if (!CollectionUtils.isEmpty(addEntityList)) { entityService.saveDomainObjects(addEntityList); summaryResponse.setAddedRecords(addEntityList.size()); } if (!CollectionUtils.isEmpty(updateEntityList)) { entityService.updateDomainObjects(updateEntityList); summaryResponse.setUpdatedRecords(updateEntityList.size()); } if (!CollectionUtils.isEmpty(deleteEntityList)) { entityService.deleteDomainObjects(deleteEntityList); summaryResponse.setDeletedRecords(deleteEntityList.size()); } return summaryResponse; } private LocalizedException createNullExtensionException(final String extension) { return new LocalizedException("file.extension.null", new String[] { extension }); } private LocalizedException createFileExtensionException(final String extension) { return new LocalizedException("file.invlaid.fileformat", new String[] { extension }); } private LocalizedException createInvalidTypeException(final String fileType) { return new LocalizedException("file.invalid.filetype", new String[] { fileType }); } }