/** * \brief Decode the length field of a TLV-entry. * * <p>The length field itself can be 1, 2 or 3 bytes long: - If the length is between 0 and 127, * it is 1 byte long. - If the length is between 128 and 255, it is 2 bytes long. The first byte * is 0x81 to indicate this. - If the length is between 256 and 65535, it is 3 bytes long. The * first byte is 0x82, the following 2 contain the actual length. Note: Only lengths up to 0x7FFF * (32767) are supported here, because a short in Java is signed. * * <p>\param buf The buffer containing the length field. * * <p>\param offset The offset at where the length field starts. * * <p>\param length The length of the buffer (buf). This is to prevent that the index gets out of * bounds. * * <p>\return The (positive) length encoded by the length field, or in case of an error, -1. * * <p>\throw InvalidArgumentsException If offset is too big for a signed Java short If the first * byte of the length field is invalid */ public static short decodeLengthField(byte[] buf, short offset) throws InvalidArgumentsException { if (buf[offset] == (byte) 0x82) { // 256..65535 // Check for short overflow // (In Java, a short is signed: positive values are 0000..7FFF) if (buf[(short) (offset + 1)] < 0) { // 80..FF throw InvalidArgumentsException.getInstance(); } return Util.getShort(buf, (short) (offset + 1)); } else if (buf[offset] == (byte) 0x81) { return (short) (0x00FF & buf[(short) (offset + 1)]); } else if (buf[offset] > 0) { // 00..7F return (short) (0x007F & buf[offset]); } else { throw InvalidArgumentsException.getInstance(); } }
/** * \brief Get the length of the length field of a TLV-entry. * * <p>\attention Not the length of the value-field is returned, but the length of the length field * itself. * * <p>\see decodeLengthField() * * <p>\param length The decoded length from the TLV-entry. * * <p>\return The length of the length field. * * <p>\throw InvalidArgumentsException If the length would overflow the signed short of Java. */ public static short getEncodingLengthFieldLength(short length) throws InvalidArgumentsException { if (length < 0) { throw InvalidArgumentsException.getInstance(); } else if (length < 128) { return 1; } else if (length < 256) { return 2; } else { return 3; } }
@ApiOperation( value = "Upload a file with certified products", notes = "Accepts a CSV file with very specific fields to create pending certified products. " + " The user uploading the file must have ROLE_ACB_ADMIN or ROLE_ACB_STAFF " + " and administrative authority on the ACB(s) specified in the file.") @RequestMapping( value = "/upload", method = RequestMethod.POST, produces = "application/json; charset=utf-8") public @ResponseBody PendingCertifiedProductResults upload( @RequestParam("file") MultipartFile file) throws ValidationException, MaxUploadSizeExceededException { if (file.isEmpty()) { throw new ValidationException("You cannot upload an empty file!"); } if (!file.getContentType().equalsIgnoreCase("text/csv") && !file.getContentType().equalsIgnoreCase("application/vnd.ms-excel")) { throw new ValidationException("File must be a CSV document."); } List<PendingCertifiedProductDetails> uploadedProducts = new ArrayList<PendingCertifiedProductDetails>(); BufferedReader reader = null; CSVParser parser = null; try { reader = new BufferedReader(new InputStreamReader(file.getInputStream())); parser = new CSVParser(reader, CSVFormat.EXCEL); List<CSVRecord> records = parser.getRecords(); if (records.size() <= 1) { throw new ValidationException( "The file appears to have a header line with no other information. Please make sure there are at least two rows in the CSV file."); } Set<String> handlerErrors = new HashSet<String>(); List<PendingCertifiedProductEntity> cpsToAdd = new ArrayList<PendingCertifiedProductEntity>(); // parse the entire file into groups of records, one group per product CSVRecord heading = null; Set<String> uniqueIdsFromFile = new HashSet<String>(); Set<String> duplicateIdsFromFile = new HashSet<String>(); List<CSVRecord> rows = new ArrayList<CSVRecord>(); for (int i = 0; i < records.size(); i++) { CSVRecord currRecord = records.get(i); if (heading == null && !StringUtils.isEmpty(currRecord.get(1)) && currRecord.get(1).equals("RECORD_STATUS__C")) { // have to find the heading first heading = currRecord; } else if (heading != null) { if (!StringUtils.isEmpty(currRecord.get(0))) { String currUniqueId = currRecord.get(0); String currStatus = currRecord.get(1); if (currStatus.equalsIgnoreCase("NEW")) { if (!currUniqueId.contains("XXXX") && uniqueIdsFromFile.contains(currUniqueId)) { handlerErrors.add( "Multiple products with unique id " + currUniqueId + " were found in the file."); duplicateIdsFromFile.add(currUniqueId); } else { uniqueIdsFromFile.add(currUniqueId); // parse the previous recordset if (rows.size() > 0) { try { CertifiedProductUploadHandler handler = uploadHandlerFactory.getHandler(heading, rows); PendingCertifiedProductEntity pendingCp = handler.handle(); cpsToAdd.add(pendingCp); } catch (InvalidArgumentsException ex) { handlerErrors.add(ex.getMessage()); } } rows.clear(); } } if (!duplicateIdsFromFile.contains(currUniqueId)) { rows.add(currRecord); } } } // add the last object if (i == records.size() - 1 && !rows.isEmpty()) { try { CertifiedProductUploadHandler handler = uploadHandlerFactory.getHandler(heading, rows); PendingCertifiedProductEntity pendingCp = handler.handle(); cpsToAdd.add(pendingCp); } catch (InvalidArgumentsException ex) { handlerErrors.add(ex.getMessage()); } } } if (handlerErrors.size() > 0) { throw new ValidationException(handlerErrors, null); } Set<String> allErrors = new HashSet<String>(); for (PendingCertifiedProductEntity cpToAdd : cpsToAdd) { if (cpToAdd.getErrorMessages() != null && cpToAdd.getErrorMessages().size() > 0) { allErrors.addAll(cpToAdd.getErrorMessages()); } } if (allErrors.size() > 0) { throw new ValidationException(allErrors, null); } else { for (PendingCertifiedProductEntity cpToAdd : cpsToAdd) { try { PendingCertifiedProductDTO pendingCpDto = pcpManager.createOrReplace(cpToAdd.getCertificationBodyId(), cpToAdd); PendingCertifiedProductDetails details = new PendingCertifiedProductDetails(pendingCpDto); uploadedProducts.add(details); } catch (EntityCreationException ex) { logger.error("Error creating pending certified product: " + cpToAdd.getUniqueId()); } catch (EntityRetrievalException ex) { logger.error("Error retreiving pending certified product.", ex); } } } } catch (IOException ioEx) { logger.error("Could not get input stream for uploaded file " + file.getName()); throw new ValidationException( "Could not get input stream for uploaded file " + file.getName()); } finally { try { parser.close(); } catch (Exception ignore) { } try { reader.close(); } catch (Exception ignore) { } } PendingCertifiedProductResults results = new PendingCertifiedProductResults(); results.getPendingCertifiedProducts().addAll(uploadedProducts); return results; }