Example #1
0
 /**
  * Function that checks if given file is being searched Returners true if current file has a right
  * type and wasn't used more than _numOfMonth
  *
  * @param file - file to check.
  * @return true if given file fits users criteria for search
  */
 private boolean isFileSearched(File file) {
   Path p = file.toPath();
   long cutoff = System.currentTimeMillis() - ((long) _numOfMonth * 30 * 24 * 60 * 60 * 1000);
   try {
     FileTime time = (FileTime) Files.getAttribute(p, "lastAccessTime", LinkOption.NOFOLLOW_LINKS);
     long lastAccessed = time.toMillis();
     if (lastAccessed <= cutoff && file.isHidden() == false) {
       if (_word)
         if (file.getName().endsWith(".doc")
             || file.getName().endsWith(".docx")
             || file.getName().endsWith(".DOC")
             || file.getName().endsWith(".DOCX")) return true;
       if (_exel)
         if (file.getName().endsWith(".xls")
             || file.getName().endsWith(".xlsx")
             || file.getName().endsWith(".XLS")
             || file.getName().endsWith(".XLSX")) return true;
       if (_pow)
         if (file.getName().endsWith(".ppt")
             || file.getName().endsWith(".pptx")
             || file.getName().endsWith(".PPT")
             || file.getName().endsWith(".PPTX")) return true;
       if (_pdf)
         if (file.getName().endsWith(".pdf") || file.getName().endsWith(".PDF")) return true;
     }
   } catch (IOException e) {
     return false;
   }
   return false;
 }
  @Override
  public void initialize(URL location, ResourceBundle resources) {
    // TODO Auto-generated method stub
    this.tbViewColData.setCellValueFactory(cellData -> cellData.getValue().DataProperty());
    this.tbViewColArquivo.setCellValueFactory(cellData -> cellData.getValue().FileNameProperty());
    File file = new File("./relatorios/");
    if (file.exists()) {
      File[] m = file.listFiles();
      for (File f : m) {
        Path path = FileSystems.getDefault().getPath("./relatorios");
        BasicFileAttributes attributes;
        try {
          attributes = Files.readAttributes(path, BasicFileAttributes.class);
          FileTime creationTime = attributes.creationTime();
          data.add(new TableHistoricoData(creationTime.toString(), f.getPath()));
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
      this.tbViewHistorico.getItems().addAll(data);
    }

    this.tbViewHistorico.setRowFactory(
        tv -> {
          TableRow<TableHistoricoData> row = new TableRow<>();
          row.setOnMouseClicked(
              event -> {
                if (event.getClickCount() == 2 && (!row.isEmpty())) {
                  TableHistoricoData rowData = row.getItem();
                  try {
                    Thread t =
                        new Thread() {
                          public void run() {
                            if (Desktop.isDesktopSupported())
                              if (Desktop.getDesktop().isSupported(Action.OPEN)) {
                                Desktop op = Desktop.getDesktop();
                                if (new File(rowData.getFileName()).exists()) {
                                  try {
                                    op.open(new File(rowData.getFileName()));
                                  } catch (IOException e) {
                                    e.printStackTrace();
                                  }
                                }
                              }
                          }
                        };
                    t.start();
                  } catch (Exception e) {
                    e.printStackTrace();
                  }
                }
              });
          return row;
        });
  }
  @NewEnv(type = NewEnv.Type.NONE)
  @Test
  public void testGetLastModifiedTime() throws IOException {
    Assert.assertEquals(Long.MIN_VALUE, NettyRepository.getLastModifiedTime(null));
    Assert.assertEquals(Long.MIN_VALUE, NettyRepository.getLastModifiedTime(Paths.get("Unknown")));

    FileTime fileTime = Files.getLastModifiedTime(_repositoryPath);

    Assert.assertEquals(fileTime.toMillis(), NettyRepository.getLastModifiedTime(_repositoryPath));
  }
    @Override
    public void setTimes(FileTime lastModifiedTime, FileTime lastAccessTime, FileTime createTime)
        throws IOException {
      // null => don't change
      if (lastModifiedTime == null && lastAccessTime == null) {
        // no effect
        return;
      }

      // permission check
      file.checkWrite();

      int fd = file.openForAttributeAccess(followLinks);
      try {
        // if not changing both attributes then need existing attributes
        if (lastModifiedTime == null || lastAccessTime == null) {
          try {
            UnixFileAttributes attrs = UnixFileAttributes.get(fd);
            if (lastModifiedTime == null) lastModifiedTime = attrs.lastModifiedTime();
            if (lastAccessTime == null) lastAccessTime = attrs.lastAccessTime();
          } catch (UnixException x) {
            x.rethrowAsIOException(file);
          }
        }

        // uptime times
        long modValue = lastModifiedTime.to(TimeUnit.MICROSECONDS);
        long accessValue = lastAccessTime.to(TimeUnit.MICROSECONDS);

        boolean retry = false;
        try {
          futimes(fd, accessValue, modValue);
        } catch (UnixException x) {
          // if futimes fails with EINVAL and one/both of the times is
          // negative then we adjust the value to the epoch and retry.
          if (x.errno() == UnixConstants.EINVAL && (modValue < 0L || accessValue < 0L)) {
            retry = true;
          } else {
            x.rethrowAsIOException(file);
          }
        }
        if (retry) {
          if (modValue < 0L) modValue = 0L;
          if (accessValue < 0L) accessValue = 0L;
          try {
            futimes(fd, accessValue, modValue);
          } catch (UnixException x) {
            x.rethrowAsIOException(file);
          }
        }
      } finally {
        close(fd);
      }
    }
Example #5
0
  public static void main(String[] args) throws IOException {
    Path dir = Paths.get(System.getProperty("user.home"), ".sandbox");
    Files.createDirectories(dir);
    Path file = Paths.get(dir.toString(), "timestamp-test.txt");
    List<String> lines = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
      lines.add(RandomStringUtils.randomAscii(20));
    }
    Files.write(file, lines);

    FileTime fileTime = Files.getLastModifiedTime(file);
    System.out.println(fileTime);
    System.out.println(LocalDateTime.ofInstant(fileTime.toInstant(), ZoneId.systemDefault()));
  }
  /**
   * May be called to refresh the state attributes used to detect changes e.g., file existence, size
   * and last-modified time once re-loading is successfully completed. If the file does not exist
   * then the attributes are reset to an &quot;unknown&quot; state.
   *
   * @throws IOException If failed to access the file (if exists)
   * @see #resetReloadAttributes()
   */
  public void updateReloadAttributes() throws IOException {
    if (exists()) {
      long size = size();
      FileTime modifiedTime = lastModified();

      if (size >= 0L && modifiedTime != null) {
        lastExisted.set(true);
        lastSize.set(size);
        lastModified.set(modifiedTime.toMillis());
        return;
      }
    }

    resetReloadAttributes();
  }
Example #7
0
  public static boolean isModified(SyncFile syncFile, Path filePath) {
    if (filePath == null) {
      return true;
    }

    try {
      FileTime fileTime = Files.getLastModifiedTime(filePath);

      long modifiedTime = syncFile.getModifiedTime();

      if (OSDetector.isUnix()) {
        modifiedTime = modifiedTime / 1000 * 1000;
      }

      if ((fileTime.toMillis() <= modifiedTime)
          && FileKeyUtil.hasFileKey(filePath, syncFile.getSyncFileId())) {

        return false;
      }
    } catch (IOException ioe) {
      if (_logger.isDebugEnabled()) {
        _logger.debug(ioe.getMessage(), ioe);
      }
    }

    try {
      if ((syncFile.getSize() > 0) && (syncFile.getSize() != Files.size(filePath))) {

        return true;
      }
    } catch (IOException ioe) {
      if (_logger.isDebugEnabled()) {
        _logger.debug(ioe.getMessage(), ioe);
      }
    }

    try {
      String checksum = getChecksum(filePath);

      return !checksumsEqual(checksum, syncFile.getChecksum());
    } catch (IOException ioe) {
      if (_logger.isDebugEnabled()) {
        _logger.debug(ioe.getMessage(), ioe);
      }

      return true;
    }
  }
  public FakeProjectFilesystem(Clock clock, Path root, Set<Path> files) {
    super(root);
    // We use LinkedHashMap to preserve insertion order, so the
    // behavior of this test is consistent across versions. (It also lets
    // us write tests which explicitly test iterating over entries in
    // different orders.)
    fileContents = new LinkedHashMap<>();
    fileLastModifiedTimes = new LinkedHashMap<>();
    FileTime modifiedTime = FileTime.fromMillis(clock.currentTimeMillis());
    for (Path file : files) {
      fileContents.put(file, new byte[0]);
      fileLastModifiedTimes.put(file, modifiedTime);
    }
    fileAttributes = new LinkedHashMap<>();
    symLinks = new LinkedHashMap<>();
    directories = new LinkedHashSet<>();
    directories.add(Paths.get(""));
    for (Path file : files) {
      Path dir = file.getParent();
      while (dir != null) {
        directories.add(dir);
        dir = dir.getParent();
      }
    }
    this.clock = Preconditions.checkNotNull(clock);

    // Generally, tests don't care whether files exist.
    ignoreValidityOfPaths = true;
  }
Example #9
0
  @Override
  public void execute() throws IOException {
    Attributes remoteAttributes = remoteIndex.get(path);
    Path rootDirectory = Registry.getInstance().getRootDirectory();

    try {
      // TODO get rid of getRootDirectory, stupid (non)dependency
      new NetworkClient(rootDirectory).request(remoteAttributes.getAddress(), path);
    } catch (URISyntaxException e) {
      logger.error(e);
    }

    if (logger.isTraceEnabled()) {}

    logger.trace(
        String.format("Setting time on %1s to %2s", path, remoteAttributes.lastModifiedTime()));

    rootDirectory
        .resolve(path)
        .setAttribute(
            "basic:lastModifiedTime",
            FileTime.fromMillis(remoteAttributes.lastModifiedTime()),
            LinkOption.NOFOLLOW_LINKS);

    localIndex.addFromRemote(path, remoteAttributes);
  }
Example #10
0
 public void touch(Path fileToTouch) throws IOException {
   if (exists(fileToTouch)) {
     setLastModifiedTime(fileToTouch, FileTime.fromMillis(System.currentTimeMillis()));
   } else {
     createNewFile(fileToTouch);
   }
 }
 @Override
 public void mkdirs(Path path) throws IOException {
   for (int i = 0; i < path.getNameCount(); i++) {
     Path subpath = path.subpath(0, i + 1);
     directories.add(subpath);
     fileLastModifiedTimes.put(subpath, FileTime.fromMillis(clock.currentTimeMillis()));
   }
 }
Example #12
0
 @Override
 public String toString() {
   if (!initialized) {
     return Constantes.OBJECT_NOT_INITIALIZED;
   }
   return String.format(
       "%s;%04X;%d;%s;%s", hash, flags, Long.valueOf(size), lastModif.toString(), name);
 }
Example #13
0
 @Override
 public boolean equals(Object o) {
   return o == this
       || o instanceof SourceId
           && getStorage().equals(((SourceId) o).getStorage())
           && myModulePath.equals(((SourceId) o).myModulePath)
           && myMtime.equals(((SourceId) o).myMtime);
 }
Example #14
0
 // do not make updateLastAccessed synchronized
 public static void updateLastAccessed(File file) {
   try {
     Files.setAttribute(
         file.toPath(), "lastAccessTime", FileTime.fromMillis(new Date().getTime()));
   } catch (Exception e) {
     e.printStackTrace();
   }
 }
Example #15
0
  public static void setModifiedTime(Path filePath, long modifiedTime) throws IOException {

    if (!Files.exists(filePath)) {
      return;
    }

    FileTime fileTime = FileTime.fromMillis(modifiedTime);

    Files.setLastModifiedTime(filePath, fileTime);
  }
  /**
   * @return {@code true} if the watched file has probably been changed
   * @throws IOException If failed to query file data
   */
  public boolean checkReloadRequired() throws IOException {
    boolean exists = exists();
    // if existence state changed from last time
    if (exists != lastExisted.getAndSet(exists)) {
      return true;
    }

    if (!exists) {
      // file did not exist and still does not exist
      resetReloadAttributes();
      return false;
    }

    long size = size();
    if (size < 0L) {
      // means file no longer exists
      resetReloadAttributes();
      return true;
    }

    // if size changed then obviously need reload
    if (size != lastSize.getAndSet(size)) {
      return true;
    }

    FileTime modifiedTime = lastModified();
    if (modifiedTime == null) {
      // means file no longer exists
      resetReloadAttributes();
      return true;
    }

    long timestamp = modifiedTime.toMillis();
    if (timestamp != lastModified.getAndSet(timestamp)) {
      return true;
    }

    return false;
  }
  @Test
  public void testFile() throws Exception {
    byte[] data = FileServerTestUtil.createRandomData(1024);

    long lastModified = FileServerTestUtil.getFileSystemTime(System.currentTimeMillis() - Time.DAY);

    FileResponse fileResponse = new FileResponse(_path, data.length, lastModified, false);

    NoticeableFuture<FileResponse> noticeableFuture = _asyncBroker.post(_path);

    _fileResponseChannelHandler.channelRead(
        _channelHandlerContext, fileResponse, FileServerTestUtil.wrapFirstHalf(data));

    ChannelHandler channelHandler = _channelPipeline.first();

    Assert.assertTrue(channelHandler instanceof FileUploadChannelHandler);

    FileUploadChannelHandler fileUploadChannelHandler = (FileUploadChannelHandler) channelHandler;

    _channelPipeline.fireChannelRead(FileServerTestUtil.wrapSecondHalf(data));

    channelHandler = _channelPipeline.first();

    Assert.assertFalse(channelHandler instanceof FileUploadChannelHandler);
    Assert.assertSame(fileResponse, fileUploadChannelHandler.fileResponse);
    Assert.assertSame(fileResponse, noticeableFuture.get());

    Path localFile = fileResponse.getLocalFile();

    Assert.assertNotNull(localFile);

    FileTime fileTime = Files.getLastModifiedTime(localFile);

    Assert.assertEquals(lastModified, fileTime.toMillis());
    Assert.assertArrayEquals(data, Files.readAllBytes(localFile));

    Files.delete(localFile);
  }
  @Override
  public void writeBytesToPath(byte[] bytes, Path path, FileAttribute<?>... attrs)
      throws IOException {
    Path normalizedPath = MorePaths.normalize(path);
    fileContents.put(normalizedPath, Preconditions.checkNotNull(bytes));
    fileAttributes.put(normalizedPath, ImmutableSet.copyOf(attrs));

    Path directory = normalizedPath.getParent();
    while (directory != null) {
      directories.add(directory);
      directory = directory.getParent();
    }
    fileLastModifiedTimes.put(normalizedPath, FileTime.fromMillis(clock.currentTimeMillis()));
  }
Example #19
0
 /**
  * @param line structured as SHA256;0000;size;YYYY-MM-DDTHH:MM:SS;name
  * @throws IllegalArgumentException
  */
 public FileInfo(String line) throws IllegalArgumentException {
   if (line == null) {
     throw new IllegalArgumentException("line must not be null");
   }
   String[] fields = line.split(";");
   if (fields.length < 5) {
     throw new IllegalArgumentException(
         String.format("line has %d fields instead of 5", fields.length));
   }
   byte[] hex = null;
   try {
     hex = DatatypeConverter.parseHexBinary(fields[0]);
   } catch (IllegalArgumentException e) {
     // exception handled below
   }
   if (hex == null || hex.length != HASH_BYTES) {
     throw new IllegalArgumentException(
         String.format("%s is not a valid SHA-256 signature", fields[0]));
   }
   hash = fields[0];
   int val = -1;
   try {
     val = Integer.parseInt(fields[1], 16);
   } catch (NumberFormatException e) {
     // exception handled below
   }
   if (val == -1 || fields[1].length() != 4) {
     throw new IllegalArgumentException(
         String.format("%s is not a valid 16 bit status", fields[1]));
   }
   flags = val;
   long len = -1;
   try {
     len = Long.parseLong(fields[2]);
   } catch (NumberFormatException e) {
     // exception handled below
   }
   if (len == -1) {
     throw new IllegalArgumentException(String.format("%s is not a valid size", fields[2]));
   }
   size = len;
   Instant instant = null;
   try {
     instant = Instant.parse(fields[3]);
   } catch (DateTimeParseException e) {
     // exception handled below
   }
   if (instant == null) {
     throw new IllegalArgumentException(String.format("%s is not a valid timestamp", fields[3]));
   }
   lastModif = FileTime.from(instant);
   StringBuffer finLigne = new StringBuffer(fields[4]);
   for (int i = 5; i < fields.length; i++) {
     finLigne.append(";").append(fields[i]);
   }
   if (finLigne.length() == 0) {
     throw new IllegalArgumentException(String.format("file name is empty"));
   }
   name = finLigne.toString();
   initialized = true;
 }
Example #20
0
 public FileTime secondFileTime(FileTime lastModif) {
   long millis = lastModif.toMillis();
   long diff = millis % 1000;
   return FileTime.fromMillis(millis - diff);
 }
Example #21
0
 /** Converts "standard Unix time"(in seconds, UTC/GMT) to FileTime */
 public static final FileTime unixTimeToFileTime(long utime) {
   return FileTime.from(utime, TimeUnit.SECONDS);
 }
  protected void sendFile(
      final ChannelHandlerContext channelHandlerContext,
      FullHttpRequest fullHttpRequest,
      SyncFile syncFile)
      throws Exception {

    Path path = Paths.get(syncFile.getFilePathName());

    if (Files.notExists(path)) {
      _syncTrafficShapingHandler.decrementConnectionsCount();

      if (_logger.isTraceEnabled()) {
        Channel channel = channelHandlerContext.channel();

        _logger.trace("Client {}: file not found {}", channel.remoteAddress(), path);
      }

      _sendError(channelHandlerContext, NOT_FOUND);

      return;
    }

    if (_logger.isDebugEnabled()) {
      Channel channel = channelHandlerContext.channel();

      _logger.debug("Client {}: sending file {}", channel.remoteAddress(), path);
    }

    long modifiedTime = syncFile.getModifiedTime();
    long previousModifiedTime = syncFile.getPreviousModifiedTime();

    if (OSDetector.isApple()) {
      modifiedTime = modifiedTime / 1000 * 1000;
      previousModifiedTime = previousModifiedTime / 1000 * 1000;
    }

    FileTime currentFileTime = Files.getLastModifiedTime(path, LinkOption.NOFOLLOW_LINKS);

    long currentTime = currentFileTime.toMillis();

    if ((currentTime != modifiedTime) && (currentTime != previousModifiedTime)) {

      _syncTrafficShapingHandler.decrementConnectionsCount();

      Channel channel = channelHandlerContext.channel();

      _logger.error(
          "Client {}: file modified {}, currentTime {}, modifiedTime "
              + "{}, previousModifiedTime {}",
          channel.remoteAddress(),
          path,
          currentTime,
          modifiedTime,
          previousModifiedTime);

      _sendError(channelHandlerContext, NOT_FOUND);

      return;
    }

    HttpResponse httpResponse = new DefaultHttpResponse(HTTP_1_1, OK);

    long size = Files.size(path);

    HttpUtil.setContentLength(httpResponse, size);

    HttpHeaders httpHeaders = httpResponse.headers();

    MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();

    httpHeaders.set(
        HttpHeaderNames.CONTENT_TYPE, mimetypesFileTypeMap.getContentType(syncFile.getName()));

    if (HttpUtil.isKeepAlive(fullHttpRequest)) {
      httpHeaders.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
    }

    channelHandlerContext.write(httpResponse);

    SyncChunkedFile syncChunkedFile = new SyncChunkedFile(path, size, 4 * 1024 * 1024, currentTime);

    ChannelFuture channelFuture =
        channelHandlerContext.writeAndFlush(
            new HttpChunkedInput(syncChunkedFile), channelHandlerContext.newProgressivePromise());

    channelFuture.addListener(
        new ChannelFutureListener() {

          @Override
          public void operationComplete(ChannelFuture channelFuture) throws Exception {

            _syncTrafficShapingHandler.decrementConnectionsCount();

            if (channelFuture.isSuccess()) {
              return;
            }

            Throwable exception = channelFuture.cause();

            Channel channel = channelHandlerContext.channel();

            _logger.error(
                "Client {}: {}", channel.remoteAddress(), exception.getMessage(), exception);

            channelHandlerContext.close();
          }
        });

    if (!HttpUtil.isKeepAlive(fullHttpRequest)) {
      channelFuture.addListener(ChannelFutureListener.CLOSE);
    }
  }
Example #23
0
 public long getLastModified() {
   return myMtime.toMillis();
 }
Example #24
0
 public SourceId locateModule(ModulePath modulePath, long mtime) {
   return new SourceId(modulePath, FileTime.fromMillis(mtime));
 }
Example #25
0
 /** Converts FileTime to Windows time. */
 public static final long fileTimeToWinTime(FileTime ftime) {
   return (ftime.to(TimeUnit.MICROSECONDS) - WINDOWS_EPOCH_IN_MICROSECONDS) * 10;
 }
/** @author Emmanuel Hugonnet (c) 2016 Red Hat, inc. */
public class ContentRepositoryTest {

  private static final boolean IS_WINDOWS =
      AccessController.doPrivileged(
          (PrivilegedAction<Boolean>)
              () ->
                  System.getProperty("os.name", null)
                      .toLowerCase(Locale.ENGLISH)
                      .contains("windows"));
  private static final FileTime time = FileTime.from(Instant.parse("2007-12-03T10:15:30.00Z"));

  private ContentRepository repository;
  private final File rootDir = new File("target", "repository");
  private final File tmpRootDir = new File("target", "tmp");

  public ContentRepositoryTest() {}

  @Before
  public void createRepository() throws IOException {
    if (rootDir.exists()) {
      deleteRecursively(rootDir.toPath());
    }
    rootDir.mkdirs();
    if (tmpRootDir.exists()) {
      deleteRecursively(tmpRootDir.toPath());
    }
    tmpRootDir.mkdirs();
    repository = ContentRepository.Factory.create(rootDir, tmpRootDir, 0L);
  }

  @After
  public void destroyRepository() throws IOException {
    deleteRecursively(rootDir.toPath());
    deleteRecursively(tmpRootDir.toPath());
    repository = null;
  }

  private String readFileContent(Path path) throws Exception {
    try (InputStream in = getFileInputStream(path)) {
      return readFileContent(in);
    }
  }

  private String readFileContent(InputStream in) throws Exception {
    try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
      byte[] buffer = new byte[8];
      int length = 8;
      while ((length = in.read(buffer, 0, length)) > 0) {
        out.write(buffer, 0, length);
      }
      return out.toString("UTF-8");
    }
  }

  /** Test of addContent method, of class ContentRepository. */
  @Test
  public void testAddContent() throws Exception {
    try (InputStream stream = getResourceAsStream("overlay.xhtml")) {
      String expResult = "0c40ffacd15b0f66d5081a93407d3ff5e3c65a71";
      byte[] result = repository.addContent(stream);
      assertThat(result, is(notNullValue()));
      assertThat(HashUtil.bytesToHexString(result), is(expResult));
    }
  }

  /** Test of explodeContent method, of class ContentRepository. */
  @Test
  public void testExplodeContent() throws Exception {
    byte[] archive = createArchive(Collections.singletonList("overlay.xhtml"));
    try (ByteArrayInputStream stream = new ByteArrayInputStream(archive)) {
      byte[] hash = repository.explodeContent(repository.addContent(stream));
      String expResult = "b1f18e286615dda0643633ec31f1a17d90e48875";
      // hash is different from the simple overlay.xhtml as we add the content folder name in the
      // computation
      assertThat(hash, is(notNullValue()));
      Path content = repository.getContent(hash).getPhysicalFile().toPath();
      String contentHtml = readFileContent(content.resolve("overlay.xhtml"));
      String expectedContentHtml = readFileContent(getResourceAsStream("overlay.xhtml"));
      assertThat(contentHtml, is(expectedContentHtml));
      assertThat(HashUtil.bytesToHexString(hash), is(expResult));
    }
  }

  /** Test of explodeContent method, of class ContentRepository. */
  @Test
  public void testExplodeSubContent() throws Exception {
    byte[] archive =
        createMultiLevelArchive(Collections.singletonList("overlay.xhtml"), "test/archive.zip");
    try (ByteArrayInputStream stream = new ByteArrayInputStream(archive)) {
      byte[] originalHash = repository.addContent(stream);
      assertThat(originalHash, is(notNullValue()));
      assertThat(
          HashUtil.bytesToHexString(originalHash), is("f11be1883895957b06f7e46d784cad60dd015d71"));
      try {
        repository.explodeSubContent(originalHash, "test/archive.zip");
        fail("Shouldn't be able to explode sub content of unexploded content");
      } catch (ExplodedContentException ex) {
      }
      byte[] hash = repository.explodeContent(originalHash);
      // hash is different from the simple overlay.xhtml as we add the content folder name in the
      // computation
      assertThat(hash, is(notNullValue()));
      assertThat(HashUtil.bytesToHexString(hash), is("5ab326c763fadad903d0e9bbfecbb42e69a1b8b4"));
      Path content = repository.getContent(hash).getPhysicalFile().toPath();
      String contentHtml = readFileContent(content.resolve("overlay.xhtml"));
      String expectedContentHtml = readFileContent(getResourceAsStream("overlay.xhtml"));
      assertThat(contentHtml, is(expectedContentHtml));
      Path archiveFile = content.resolve("test").resolve("archive.zip");
      assertTrue(Files.exists(archiveFile));
      assertTrue(PathUtil.isArchive(archiveFile));
      byte[] fullyExplodedHash = repository.explodeSubContent(hash, "test/archive.zip");
      assertThat(fullyExplodedHash, is(notNullValue()));
      assertThat(
          HashUtil.bytesToHexString(fullyExplodedHash),
          is("231f4d042711f017d7f8c45aa4affcccbd4d67f4"));
      content =
          repository
              .getContent(repository.explodeSubContent(hash, "test/archive.zip"))
              .getPhysicalFile()
              .toPath();
      Path directory = content.resolve("test").resolve("archive.zip");
      assertTrue("Should not be a zip file", Files.isDirectory(directory));
      assertThat(contentHtml, is(expectedContentHtml));
    }
  }

  private byte[] createMultiLevelArchive(List<String> resources, String archivePath)
      throws IOException {
    try (ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
      try (ZipOutputStream out = new ZipOutputStream(buffer)) {
        for (String resourcePath : resources) {
          ZipEntry entry = new ZipEntry(resourcePath);
          entry.setLastModifiedTime(time);
          out.putNextEntry(entry);
          try (InputStream in = getResourceAsStream(resourcePath)) {
            StreamUtils.copyStream(in, out);
          }
          out.closeEntry();
        }
        ZipEntry entry = new ZipEntry("test/");
        entry.setLastModifiedTime(time);
        out.putNextEntry(entry);
        out.closeEntry();
        entry = new ZipEntry(archivePath);
        entry.setLastModifiedTime(time);
        out.putNextEntry(entry);
        try (InputStream in = new ByteArrayInputStream(createArchive(resources))) {
          StreamUtils.copyStream(in, out);
        }
        out.closeEntry();
      }
      return buffer.toByteArray();
    }
  }

  private byte[] createArchive(List<String> resources) throws IOException {
    try (ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
      try (ZipOutputStream out = new ZipOutputStream(buffer)) {
        for (String resourcePath : resources) {
          ZipEntry entry = new ZipEntry(resourcePath);
          entry.setLastModifiedTime(time);
          out.putNextEntry(entry);
          try (InputStream in = getResourceAsStream(resourcePath)) {
            StreamUtils.copyStream(in, out);
          }
          out.closeEntry();
        }
      }
      return buffer.toByteArray();
    }
  }

  private byte[] createContentArchive() throws IOException {
    try (ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
      try (ZipOutputStream out = new ZipOutputStream(buffer)) {
        ZipEntry entry = new ZipEntry("overlay.xhtml");
        entry.setLastModifiedTime(time);
        out.putNextEntry(entry);
        try (InputStream in = getResourceAsStream("overlay.xhtml")) {
          StreamUtils.copyStream(in, out);
        }
        out.closeEntry();
        entry = new ZipEntry("test.jsp");
        entry.setLastModifiedTime(time);
        out.putNextEntry(entry);
        try (InputStream in =
            new ByteArrayInputStream("this is a test".getBytes(StandardCharsets.UTF_8))) {
          StreamUtils.copyStream(in, out);
        }
        out.closeEntry();
        entry = new ZipEntry("empty-dir/");
        entry.setLastModifiedTime(time);
        out.putNextEntry(entry);
        out.closeEntry();
        assertTrue(entry.isDirectory());
        entry = new ZipEntry("test/");
        entry.setLastModifiedTime(time);
        out.putNextEntry(entry);
        out.closeEntry();
        assertTrue(entry.isDirectory());
        entry = new ZipEntry("test/empty-file.txt");
        entry.setLastModifiedTime(time);
        out.putNextEntry(entry);
        try (InputStream in = HashUtil.emptyStream()) {
          StreamUtils.copyStream(in, out);
        }
        out.closeEntry();
      }
      return buffer.toByteArray();
    }
  }

  /** Test of explodeContent method, of class ContentRepository. */
  @Test
  public void testChangeExplodedContent() throws Exception {
    byte[] archive = createArchive(Collections.singletonList("overlay.xhtml"));
    try (ByteArrayInputStream stream = new ByteArrayInputStream(archive)) {
      byte[] hash = repository.explodeContent(repository.addContent(stream));
      String expResult = "b1f18e286615dda0643633ec31f1a17d90e48875";
      // hash is different from the simple overlay.xhtml as we add the content folder name in the
      // computation
      assertThat(hash, is(notNullValue()));
      Path content = repository.getContent(hash).getPhysicalFile().toPath();
      String contentHtml = readFileContent(content.resolve("overlay.xhtml"));
      String expectedContentHtml = readFileContent(getResourceAsStream("overlay.xhtml"));
      assertThat(contentHtml, is(expectedContentHtml));
      assertThat(HashUtil.bytesToHexString(hash), is(expResult));
      String updatedExpectedResult = "161a2c95b16d5ffede0721c2cec984ca51009082";
      hash =
          repository.addContentToExploded(
              hash,
              Collections.singletonList(
                  new ExplodedContent(
                      "test.jsp",
                      new ByteArrayInputStream("this is a test".getBytes(StandardCharsets.UTF_8)))),
              true);
      assertThat(hash, is(notNullValue()));
      assertThat(HashUtil.bytesToHexString(hash), is(updatedExpectedResult));
      try (InputStream addedContent = repository.readContent(hash, "test.jsp")) {
        assertThat(addedContent, is(notNullValue()));
        assertThat(readFileContent(addedContent), is("this is a test"));
      }
      content = repository.getContent(hash).getPhysicalFile().toPath();
      assertThat(content.toFile().list().length, is(2));
      hash = repository.removeContentFromExploded(hash, Collections.singletonList("test.jsp"));
      assertThat(hash, is(notNullValue()));
      assertThat(HashUtil.bytesToHexString(hash), is(expResult));
      updatedExpectedResult = "a44921155d75009d885db3357005b85b435cf59f";
      hash =
          repository.addContentToExploded(
              hash,
              Collections.singletonList(
                  new ExplodedContent(
                      "test.jsp",
                      new ByteArrayInputStream(
                          "this is an overwrite test".getBytes(StandardCharsets.UTF_8)))),
              true);
      assertThat(hash, is(notNullValue()));
      assertThat(HashUtil.bytesToHexString(hash), is(updatedExpectedResult));
      try (InputStream addedContent = repository.readContent(hash, "test.jsp")) {
        assertThat(addedContent, is(notNullValue()));
        assertThat(readFileContent(addedContent), is("this is an overwrite test"));
      }
      try {
        hash =
            repository.addContentToExploded(
                hash,
                Collections.singletonList(
                    new ExplodedContent(
                        "test.jsp",
                        new ByteArrayInputStream(
                            "this is a failure test".getBytes(StandardCharsets.UTF_8)))),
                false);
        fail("Overwritting shouldn't work");
      } catch (ExplodedContentException ex) {
      }
    }
  }

  @Test
  public void testListContents() throws Exception {
    byte[] archive = createArchive(Collections.singletonList("overlay.xhtml"));
    try (ByteArrayInputStream stream = new ByteArrayInputStream(archive)) {
      byte[] hash = repository.explodeContent(repository.addContent(stream));
      String expResult = "b1f18e286615dda0643633ec31f1a17d90e48875";
      // hash is different from the simple overlay.xhtml as we add the content folder name in the
      // computation
      assertThat(hash, is(notNullValue()));
      Path content = repository.getContent(hash).getPhysicalFile().toPath();
      String contentHtml = readFileContent(content.resolve("overlay.xhtml"));
      String expectedContentHtml = readFileContent(getResourceAsStream("overlay.xhtml"));
      assertThat(contentHtml, is(expectedContentHtml));
      assertThat(HashUtil.bytesToHexString(hash), is(expResult));
      String updatedExpectedResult = "161a2c95b16d5ffede0721c2cec984ca51009082";
      hash =
          repository.addContentToExploded(
              hash,
              Collections.singletonList(
                  new ExplodedContent(
                      "test.jsp",
                      new ByteArrayInputStream("this is a test".getBytes(StandardCharsets.UTF_8)))),
              true);
      assertThat(hash, is(notNullValue()));
      assertThat(HashUtil.bytesToHexString(hash), is(updatedExpectedResult));
      List<String> contents =
          repository
              .listContent(hash, "", ContentFilter.Factory.createContentFilter(-1, false))
              .stream()
              .map(ContentRepositoryElement::getPath)
              .collect(Collectors.toList());
      assertThat(contents.size(), is(2));
      assertThat(contents, CoreMatchers.hasItems("test.jsp", "overlay.xhtml"));
      hash =
          repository.addContentToExploded(
              hash,
              Collections.singletonList(new ExplodedContent("test/empty-file.txt", emptyStream())),
              true);
      hash =
          repository.addContentToExploded(
              hash, Collections.singletonList(new ExplodedContent("empty-dir", null)), true);
      contents =
          repository
              .listContent(hash, "", ContentFilter.Factory.createContentFilter(-1, false))
              .stream()
              .map(ContentRepositoryElement::getPath)
              .collect(Collectors.toList());
      assertThat(contents, is(notNullValue()));
      assertThat(contents.size(), is(5));
      assertThat(
          contents,
          CoreMatchers.hasItems(
              "test.jsp", "overlay.xhtml", "test/empty-file.txt", "test/", "empty-dir/"));
      hash = repository.removeContentFromExploded(hash, Collections.singletonList("test.jsp"));
      contents =
          repository
              .listContent(hash, "", ContentFilter.Factory.createFileFilter(-1, false))
              .stream()
              .map(ContentRepositoryElement::getPath)
              .collect(Collectors.toList());
      assertThat(contents, is(notNullValue()));
      assertThat(contents.size(), is(2));
      assertThat(contents, CoreMatchers.hasItems("overlay.xhtml", "test/empty-file.txt"));
    }
  }

  @Test
  public void testListArchiveContents() throws Exception {
    byte[] archive = createContentArchive();
    try (ByteArrayInputStream stream = new ByteArrayInputStream(archive)) {
      byte[] hash = repository.addContent(stream);
      // hash is different from the simple overlay.xhtml as we add the content folder name in the
      // computation
      assertThat(hash, is(notNullValue()));
      List<String> contents =
          repository
              .listContent(hash, "", ContentFilter.Factory.createContentFilter(-1, false))
              .stream()
              .map(ContentRepositoryElement::getPath)
              .collect(Collectors.toList());
      assertThat(contents.size(), is(5));
      assertThat(
          contents,
          CoreMatchers.hasItems(
              "test.jsp", "overlay.xhtml", "test/empty-file.txt", "test/", "empty-dir/"));
      hash =
          repository.addContentToExploded(
              hash,
              Collections.singletonList(new ExplodedContent("test/empty-file.txt", emptyStream())),
              true);
      hash =
          repository.addContentToExploded(
              hash, Collections.singletonList(new ExplodedContent("empty-dir", null)), true);
      contents =
          repository
              .listContent(hash, "", ContentFilter.Factory.createContentFilter(1, false))
              .stream()
              .map(ContentRepositoryElement::getPath)
              .collect(Collectors.toList());
      assertThat(contents, is(notNullValue()));
      assertThat(contents.size(), is(4));
      assertThat(
          contents, CoreMatchers.hasItems("test.jsp", "overlay.xhtml", "test/", "empty-dir/"));
      contents =
          repository
              .listContent(hash, "", ContentFilter.Factory.createFileFilter(-1, false))
              .stream()
              .map(ContentRepositoryElement::getPath)
              .collect(Collectors.toList());
      assertThat(contents, is(notNullValue()));
      assertThat(contents.size(), is(3));
      assertThat(
          contents, CoreMatchers.hasItems("test.jsp", "overlay.xhtml", "test/empty-file.txt"));
    }
  }

  /** Test of addContentReference method, of class ContentRepository. */
  @Test
  public void testAddContentReference() throws Exception {
    try (InputStream stream = getResourceAsStream("overlay.xhtml")) {
      String expResult = "0c40ffacd15b0f66d5081a93407d3ff5e3c65a71";
      byte[] result = repository.addContent(stream);
      assertThat(result, is(notNullValue()));
      assertThat(HashUtil.bytesToHexString(result), is(expResult));
      ContentReference reference = new ContentReference("contentReferenceIdentifier", result);
      repository.addContentReference(reference);
    }
  }

  /** Test of getContent method, of class ContentRepository. */
  @Test
  public void testGetContent() throws Exception {
    try (InputStream stream = getResourceAsStream("overlay.xhtml")) {
      String expResult = "0c40ffacd15b0f66d5081a93407d3ff5e3c65a71";
      byte[] result = repository.addContent(stream);
      assertThat(result, is(notNullValue()));
      assertThat(HashUtil.bytesToHexString(result), is(expResult));
      Path content = repository.getContent(result).getPhysicalFile().toPath();
      String contentHtml = readFileContent(content);
      String expectedContentHtml = readFileContent(getResourceAsStream("overlay.xhtml"));
      assertThat(contentHtml, is(expectedContentHtml));
    }
  }

  /** Test of hasContent method, of class ContentRepository. */
  @Test
  public void testHasContent() throws Exception {
    String expResult = "0c40ffacd15b0f66d5081a93407d3ff5e3c65a71";
    try (InputStream stream = getResourceAsStream("overlay.xhtml")) {
      assertThat(repository.hasContent(HashUtil.hexStringToByteArray(expResult)), is(false));
      byte[] result = repository.addContent(stream);
      assertThat(result, is(notNullValue()));
      assertThat(HashUtil.bytesToHexString(result), is(expResult));
      assertThat(repository.hasContent(HashUtil.hexStringToByteArray(expResult)), is(true));
    }
  }

  /** Test of removeContent method, of class ContentRepository. */
  @Test
  public void testRemoveContent() throws Exception {
    String expResult = "0c40ffacd15b0f66d5081a93407d3ff5e3c65a71";
    Path grandparent = rootDir.toPath().resolve("0c");
    Path parent = grandparent.resolve("40ffacd15b0f66d5081a93407d3ff5e3c65a71");
    Path expectedContent = parent.resolve("content");
    assertFalse(expectedContent + " shouldn't exist", Files.exists(expectedContent));
    assertFalse(expectedContent.getParent() + " shouldn't exist", Files.exists(parent));
    assertFalse(
        expectedContent.getParent().getParent() + " shouldn't exist", Files.exists(grandparent));
    byte[] result;
    try (InputStream stream = getResourceAsStream("overlay.xhtml")) {
      assertThat(repository.hasContent(HashUtil.hexStringToByteArray(expResult)), is(false));
      result = repository.addContent(stream);
    }
    assertThat(result, is(notNullValue()));
    assertThat(HashUtil.bytesToHexString(result), is(expResult));
    assertThat(repository.hasContent(HashUtil.hexStringToByteArray(expResult)), is(true));
    assertTrue(expectedContent + " should have been created", Files.exists(expectedContent));
    assertTrue(parent + " should have been created", Files.exists(parent));
    assertTrue(grandparent + " should have been created", Files.exists(grandparent));
    repository.removeContent(new ContentReference("overlay.xhtml", expResult));
    assertThat(repository.hasContent(HashUtil.hexStringToByteArray(expResult)), is(false));
    assertFalse(expectedContent + " should have been deleted", Files.exists(expectedContent));
    assertFalse(parent.toAbsolutePath() + " should have been deleted", Files.exists(parent));
    assertFalse(grandparent + " should have been deleted", Files.exists(grandparent));
    Path content = repository.getContent(result).getPhysicalFile().toPath();
    assertFalse(Files.exists(content));
  }

  /** Test that an empty dir will be removed during cleaning. */
  @Test
  public void testCleanEmptyParentDir() throws Exception {
    File emptyGrandParent = new File(rootDir, "ae");
    emptyGrandParent.mkdir();
    File emptyParent = new File(emptyGrandParent, "ffacd15b0f66d5081a93407d3ff5e3c65a71");
    emptyParent.mkdir();
    assertThat(emptyGrandParent.exists(), is(true));
    assertThat(emptyParent.exists(), is(true));
    Map<String, Set<String>> result =
        repository.cleanObsoleteContent(); // To mark content for deletion
    assertThat(result.get(ContentRepository.MARKED_CONTENT).size(), is(1));
    assertThat(result.get(ContentRepository.DELETED_CONTENT).size(), is(0));
    assertThat(
        result.get(ContentRepository.MARKED_CONTENT).contains(emptyParent.getAbsolutePath()),
        is(true));
    Thread.sleep(10);
    result = repository.cleanObsoleteContent();
    assertThat(emptyGrandParent.exists(), is(false));
    assertThat(emptyParent.exists(), is(false));
    assertThat(result.get(ContentRepository.MARKED_CONTENT).size(), is(0));
    assertThat(result.get(ContentRepository.DELETED_CONTENT).size(), is(1));
    assertThat(
        result.get(ContentRepository.DELETED_CONTENT).contains(emptyParent.getAbsolutePath()),
        is(true));
  }

  /** Test that an empty dir will be removed during cleaning. */
  @Test
  public void testCleanEmptyGrandParentDir() throws Exception {
    File emptyGrandParent = new File(rootDir, "ae");
    emptyGrandParent.mkdir();
    assertThat(emptyGrandParent.exists(), is(true));
    Map<String, Set<String>> result =
        repository.cleanObsoleteContent(); // Mark content for deletion
    assertThat(result.get(ContentRepository.MARKED_CONTENT).size(), is(1));
    assertThat(result.get(ContentRepository.DELETED_CONTENT).size(), is(0));
    assertThat(
        result.get(ContentRepository.MARKED_CONTENT).contains(emptyGrandParent.getAbsolutePath()),
        is(true));
    Thread.sleep(10);
    result = repository.cleanObsoleteContent();
    assertThat(emptyGrandParent.exists(), is(false));
    assertThat(result.get(ContentRepository.DELETED_CONTENT).size(), is(1));
    assertThat(result.get(ContentRepository.MARKED_CONTENT).size(), is(0));
    assertThat(
        result.get(ContentRepository.DELETED_CONTENT).contains(emptyGrandParent.getAbsolutePath()),
        is(true));
  }

  /**
   * Test that an empty dir with a system metadata file .DS_Store will be removed during cleaning.
   */
  @Test
  public void testCleanEmptyParentDirWithSystemMetaDataFile() throws Exception {
    File emptyGrandParent = new File(rootDir, "ae");
    emptyGrandParent.mkdir();
    File metaDataFile = new File(emptyGrandParent, ".DS_Store");
    metaDataFile.createNewFile();
    assertThat(emptyGrandParent.exists(), is(true));
    assertThat(metaDataFile.exists(), is(true));
    Map<String, Set<String>> result =
        repository.cleanObsoleteContent(); // To mark content for deletion
    assertThat(result.get(ContentRepository.MARKED_CONTENT).size(), is(1));
    assertThat(result.get(ContentRepository.DELETED_CONTENT).size(), is(0));
    assertThat(
        result.get(ContentRepository.MARKED_CONTENT).contains(metaDataFile.getAbsolutePath()),
        is(true));
    Thread.sleep(10);
    result = repository.cleanObsoleteContent();
    assertThat(emptyGrandParent.exists(), is(false));
    assertThat(metaDataFile.exists(), is(false));
    assertThat(result.get(ContentRepository.MARKED_CONTENT).size(), is(0));
    assertThat(result.get(ContentRepository.DELETED_CONTENT).size(), is(1));
    assertThat(
        result.get(ContentRepository.DELETED_CONTENT).contains(metaDataFile.getAbsolutePath()),
        is(true));
  }

  /** Test that an empty dir will be removed during cleaning. */
  @Test
  public void testCleanNotEmptyGrandParentDir() throws Exception {
    String expResult = "0c40ffacd15b0f66d5081a93407d3ff5e3c65a71";
    Path grandparent = rootDir.toPath().resolve("0c");
    Path parent = grandparent.resolve("40ffacd15b0f66d5081a93407d3ff5e3c65a71");
    Path other = grandparent.resolve("40ffacd15b0f66d5081a93407d3ff5e3c65a81");
    Files.createDirectories(other);
    Path expectedContent = parent.resolve("content");
    assertFalse(expectedContent + " shouldn't exist", Files.exists(expectedContent));
    assertFalse(parent + " shouldn't exist", Files.exists(parent));
    byte[] result;
    try (InputStream stream = getResourceAsStream("overlay.xhtml")) {
      assertThat(repository.hasContent(HashUtil.hexStringToByteArray(expResult)), is(false));
      result = repository.addContent(stream);
    }
    assertThat(result, is(notNullValue()));
    assertThat(HashUtil.bytesToHexString(result), is(expResult));
    assertThat(repository.hasContent(HashUtil.hexStringToByteArray(expResult)), is(true));
    assertTrue(expectedContent + " should have been created", Files.exists(expectedContent));
    assertTrue(parent + " should have been created", Files.exists(parent));
    repository.removeContent(new ContentReference("overlay.xhtml", expResult));
    assertFalse(repository.hasContent(HashUtil.hexStringToByteArray(expResult)));
    assertFalse(expectedContent + " should have been deleted", Files.exists(expectedContent));
    assertFalse(parent.toAbsolutePath() + " should have been deleted", Files.exists(parent));
    assertTrue(other + " should not have been deleted", Files.exists(other));
    assertTrue(grandparent + " should not have been deleted", Files.exists(grandparent));
    Path content = repository.getContent(result).getPhysicalFile().toPath();
    assertFalse(Files.exists(content));
  }

  /** Test that an dir not empty with no content will not be removed during cleaning. */
  @Test
  public void testNotEmptyDir() throws Exception {
    Path parentDir = rootDir.toPath().resolve("ae").resolve("ffacd15b0f66d5081a93407d3ff5e3c65a71");
    Path overlay = parentDir.resolve("overlay.xhtml");
    Path content = parentDir.resolve("content");
    Files.createDirectories(overlay.getParent());
    try (InputStream stream = getResourceAsStream("overlay.xhtml")) {
      Files.copy(stream, overlay);
      Files.copy(overlay, content);
      assertThat(Files.exists(content), is(true));
      assertThat(Files.exists(overlay), is(true));
      Map<String, Set<String>> result =
          repository.cleanObsoleteContent(); // Mark content for deletion
      assertThat(result.get(ContentRepository.MARKED_CONTENT).size(), is(1));
      assertThat(result.get(ContentRepository.DELETED_CONTENT).size(), is(0));
      assertThat(
          result
              .get(ContentRepository.MARKED_CONTENT)
              .contains(parentDir.toFile().getAbsolutePath()),
          is(true));
      Thread.sleep(10);
      result = repository.cleanObsoleteContent();
      assertThat(Files.exists(content), is(false));
      assertThat(Files.exists(overlay), is(true));
      assertThat(result.get(ContentRepository.MARKED_CONTENT).size(), is(0));
      assertThat(result.get(ContentRepository.DELETED_CONTENT).size(), is(1));
      assertThat(
          result
              .get(ContentRepository.DELETED_CONTENT)
              .contains(parentDir.toFile().getAbsolutePath()),
          is(true));
    } finally {
      Files.deleteIfExists(overlay);
      Files.deleteIfExists(overlay.getParent());
      Files.deleteIfExists(overlay.getParent().getParent());
    }
  }

  private InputStream getResourceAsStream(final String name) throws IOException {
    final InputStream result = getClass().getClassLoader().getResourceAsStream(name);
    // If we're on Windows we want to replace the stream with one that ignores \r
    if (result != null && IS_WINDOWS) {
      return new CarriageReturnRemovalInputStream(result);
    }
    return result;
  }

  private InputStream getFileInputStream(final File file) throws IOException {
    if (IS_WINDOWS) {
      return new CarriageReturnRemovalInputStream(new FileInputStream(file));
    }
    return new FileInputStream(file);
  }

  private InputStream getFileInputStream(final Path path) throws IOException {
    if (IS_WINDOWS) {
      return new CarriageReturnRemovalInputStream(Files.newInputStream(path));
    }
    return Files.newInputStream(path);
  }

  private static class CarriageReturnRemovalInputStream extends InputStream {

    private final InputStream delegate;

    private CarriageReturnRemovalInputStream(final InputStream delegate) {
      this.delegate = delegate;
    }

    @Override
    public int read() throws IOException {
      int result = delegate.read();
      if (result == '\r') {
        result = delegate.read();
      }
      return result;
    }

    @Override
    public int read(final byte[] b) throws IOException {
      Objects.nonNull(b);
      int result = 0;
      while (result > -1 && result < b.length) {
        int c = read();
        if (c == -1) {
          return result == 0 ? -1 : result;
        }
        b[result++] = (byte) c;
      }
      return result;
    }

    @Override
    public int read(final byte[] b, final int off, final int len) throws IOException {
      Objects.nonNull(b);
      if (off < 0 || len < 0 || len > b.length - off) {
        throw new IndexOutOfBoundsException();
      } else if (len == 0) {
        return 0;
      }
      int result = 0;
      while (result > -1 && result < len) {
        int c = read();
        if (c == -1) {
          return result == 0 ? -1 : result;
        }
        b[off + result++] = (byte) c;
      }
      return result;
    }

    @Override
    public long skip(final long n) throws IOException {
      return delegate.skip(n);
    }

    @Override
    public int available() throws IOException {
      return delegate.available();
    }

    @Override
    public void close() throws IOException {
      delegate.close();
    }

    @Override
    public void mark(final int readlimit) {
      delegate.mark(readlimit);
    }

    @Override
    public void reset() throws IOException {
      delegate.reset();
    }

    @Override
    public boolean markSupported() {
      return delegate.markSupported();
    }
  }
}
Example #27
0
 /** Converts FileTime to "standard Unix time". */
 public static final long fileTimeToUnixTime(FileTime ftime) {
   return ftime.to(TimeUnit.SECONDS);
 }
Example #28
0
 /** Converts Windows time (in microseconds, UTC/GMT) time to FileTime. */
 public static final FileTime winTimeToFileTime(long wtime) {
   return FileTime.from(wtime / 10 + WINDOWS_EPOCH_IN_MICROSECONDS, TimeUnit.MICROSECONDS);
 }
 private void setFileCreationDate(File f, long time) throws IOException {
   BasicFileAttributeView attributes =
       Files.getFileAttributeView(f.toPath(), BasicFileAttributeView.class);
   FileTime creationTime = FileTime.fromMillis(time);
   attributes.setTimes(creationTime, creationTime, creationTime);
 }