/* This file is part of RouteConverter. RouteConverter is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. RouteConverter is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with RouteConverter; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Copyright (C) 2007 Christian Pesch. All Rights Reserved. */ package slash.navigation.download.actions; import slash.navigation.download.Checksum; import slash.navigation.download.Download; import slash.navigation.download.FileAndChecksum; import java.io.File; import java.io.IOException; import java.util.List; import java.util.logging.Logger; import static java.lang.String.format; import static java.util.logging.Logger.getLogger; import static slash.navigation.download.Checksum.createChecksum; /** * Validates a {@link Download} * * @author Christian Pesch */ public class Validator { private static final Logger log = getLogger(Validator.class.getName()); private final Download download; private boolean calculatedChecksums = false; private Boolean existsTargets, checksumsValid; public Validator(Download download) { this.download = download; } public boolean isExistsTargets() { determineExistTargets(); return existsTargets; } public boolean isChecksumsValid() throws IOException { determineChecksumsValid(); return checksumsValid; } private File getFileTarget() { File file = download.getFile().getFile(); return file.isFile() ? file : download.getTempFile(); } private void determineExistTargets() { if (existsTargets != null) return; existsTargets = true; if (!download.getFile().getFile().exists()) { log.warning(format("%s does not exist", download.getFile())); existsTargets = false; } List<FileAndChecksum> fragments = download.getFragments(); if (fragments != null) { for (FileAndChecksum fragment : fragments) { if (!fragment.getFile().exists()) { log.warning(format("%s does not exist", fragment)); existsTargets = false; } } } } public void calculateChecksums() throws IOException { if (calculatedChecksums) return; download.getFile().setActualChecksum(createChecksum(getFileTarget())); List<FileAndChecksum> fragments = download.getFragments(); if (fragments != null) for (FileAndChecksum fragment : fragments) fragment.setActualChecksum(createChecksum(fragment.getFile())); calculatedChecksums = true; } private boolean isChecksumValid(FileAndChecksum file) throws IOException { if (file.getFile().isDirectory()) return true; Checksum expected = file.getExpectedChecksum(); if (expected == null) return true; Checksum actual = file.getActualChecksum(); if (actual == null) return false; boolean lastModifiedEquals = expected.getLastModified() == null || expected.getLastModified().equals(actual.getLastModified()); if (!lastModifiedEquals) log.warning(format("%s has last modified %s but expected %s", file.getFile(), actual.getLastModified(), expected.getLastModified())); boolean hasBeenUpdatedByMe = file.getActualChecksum().laterThan(file.getExpectedChecksum()); if (hasBeenUpdatedByMe) log.info(format("%s has been updated by me on server", file.getFile())); boolean contentLengthEquals = expected.getContentLength() == null || expected.getContentLength().equals(actual.getContentLength()); if (!contentLengthEquals) log.warning(format("%s has %d bytes but expected %d", file.getFile(), actual.getContentLength(), expected.getContentLength())); boolean sha1Equals = expected.getSHA1() == null || expected.getSHA1().equals(actual.getSHA1()); if (!sha1Equals) log.warning(format("%s has SHA-1 %s but expected %s", file.getFile(), actual.getSHA1(), expected.getSHA1())); boolean valid = lastModifiedEquals && contentLengthEquals && sha1Equals || hasBeenUpdatedByMe; if (valid) log.info(format("%s has valid checksum", file.getFile())); return valid; } private void determineChecksumsValid() throws IOException { if (checksumsValid != null) return; calculateChecksums(); if (!isChecksumValid(download.getFile())) { checksumsValid = false; return; } List<FileAndChecksum> fragments = download.getFragments(); if (fragments != null) for (FileAndChecksum fragment : fragments) if (!isChecksumValid(fragment)) { checksumsValid = false; return; } checksumsValid = true; } public void expectedChecksumIsCurrentChecksum() throws IOException { calculateChecksums(); download.getFile().setExpectedChecksum(download.getFile().getActualChecksum()); } }