Java tutorial
/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE file at the root of the source * tree and available online at * * https://github.com/keeps/commons-ip */ package org.roda_project.commons_ip.utils; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.channels.ClosedByInterruptException; import java.nio.file.DirectoryNotEmptyException; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Date; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.UUID; import javax.xml.bind.DatatypeConverter; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.roda_project.commons_ip.mets_v1_11.beans.MdSecType.MdRef; import org.roda_project.commons_ip.model.IPConstants; import org.roda_project.commons_ip.model.IPFile; import org.roda_project.commons_ip.model.IPInterface; import org.roda_project.commons_ip.model.ValidationEntry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class Utils { private static final Logger LOGGER = LoggerFactory.getLogger(Utils.class); private Utils() { } public static Optional<XMLGregorianCalendar> getCurrentTime() { Optional<XMLGregorianCalendar> res = Optional.empty(); try { GregorianCalendar c = new GregorianCalendar(); Optional.of(DatatypeFactory.newInstance().newXMLGregorianCalendar(c)); } catch (DatatypeConfigurationException e) { // do nothing & return empty } return res; } public static XMLGregorianCalendar getCurrentCalendar() throws DatatypeConfigurationException { GregorianCalendar gcal = new GregorianCalendar(); gcal.setTime(new Date()); return DatatypeFactory.newInstance().newXMLGregorianCalendar(gcal); } public static String generateRandomAndPrefixedUUID() { return METSEnums.ID_PREFIX + UUID.randomUUID().toString().toUpperCase(); } public static Path copyResourceFromClasspathToDir(Class<?> resourceClass, Path dir, String resourceTempSuffix, String resourcePath) throws IOException, InterruptedException { try { Path resource = Files.createTempFile(dir, "", resourceTempSuffix); InputStream inputStream = resourceClass.getResourceAsStream(resourcePath); OutputStream outputStream = Files.newOutputStream(resource); IOUtils.copy(inputStream, outputStream); inputStream.close(); outputStream.close(); return resource; } catch (ClosedByInterruptException e) { throw new InterruptedException(); } } public static String extractedRelativePathFromHref(MdRef mdref) { return extractedRelativePathFromHref(mdref.getHref()); } public static String extractedRelativePathFromHref(String href) { String res = METSUtils.decodeHref(href); for (String prefix : IPConstants.METS_FILE_PREFIXES_TO_ACCEPT) { if (res.startsWith(prefix)) { res = res.replaceFirst(prefix, ""); break; } } return res; } /** * Deletes a directory/file * * @param path * path to the directory/file that will be deleted. in case of a * directory, if not empty, everything in it will be deleted as well. * * @throws IOException */ public static void deletePath(Path path) throws IOException { if (path == null) { return; } try { Files.delete(path); } catch (DirectoryNotEmptyException e) { LOGGER.debug("Directory is not empty. Going to delete its content as well."); try { Files.walkFileTree(path, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { Files.delete(dir); return FileVisitResult.CONTINUE; } }); } catch (IOException e1) { throw e1; } } catch (IOException e) { throw e; } } /** * Calculates checksum, closing the inputstream in the end. */ public static String calculateChecksum(InputStream is, String algorithm) throws NoSuchAlgorithmException, IOException { MessageDigest digester = MessageDigest.getInstance(algorithm); try { byte[] block = new byte[4096]; int length; while ((length = is.read(block)) > 0) { digester.update(block, 0, length); } } finally { is.close(); } return DatatypeConverter.printHexBinary(digester.digest()); } public static List<String> getFileRelativeFolders(Path basePath, Path filePath) { List<String> res = new ArrayList<>(); Path relativize = basePath.relativize(filePath).getParent(); if (relativize != null) { Iterator<Path> iterator = relativize.iterator(); while (iterator.hasNext()) { res.add(iterator.next().toString()); } } return res; } public static Optional<IPFile> validateFile(IPInterface ip, Path filePath, List<String> fileRelativeFolders, String metsChecksum, String metsChecksumAlgorithm, String metsElementId) { boolean calculateChecksum = true; Optional<IPFile> file = Optional.empty(); // validate if both mets checksum or mets algorithm are set if (StringUtils.isBlank(metsChecksum)) { ValidationUtils.addIssue(ip.getValidationReport(), ValidationConstants.CHECKSUM_NOT_SET, ValidationEntry.LEVEL.ERROR, ip.getBasePath(), filePath); calculateChecksum = false; } if (StringUtils.isBlank(metsChecksumAlgorithm)) { ValidationUtils.addIssue(ip.getValidationReport(), ValidationConstants.CHECKSUM_ALGORITHM_NOT_SET, ValidationEntry.LEVEL.ERROR, ip.getBasePath(), filePath); calculateChecksum = false; } if (calculateChecksum) { try { String computedChecksum = Utils.calculateChecksum(Files.newInputStream(filePath), metsChecksumAlgorithm); if (computedChecksum.equalsIgnoreCase(metsChecksum)) { file = Optional.of(new IPFile(filePath, fileRelativeFolders) .setChecksumAndAlgorithm(metsChecksum, metsChecksumAlgorithm)); } else { ValidationUtils.addIssue(ip.getValidationReport(), ValidationConstants.CHECKSUMS_DIFFER, ValidationEntry.LEVEL.ERROR, metsElementId, metsChecksum, metsChecksumAlgorithm, computedChecksum, ip.getBasePath(), filePath); } } catch (NoSuchAlgorithmException | IOException e) { ValidationUtils.addIssue(ip.getValidationReport(), ValidationConstants.ERROR_COMPUTING_CHECKSUM, ValidationEntry.LEVEL.ERROR, e, ip.getBasePath(), filePath); } } return file; } }