001/* 002 * JDrupes Builder 003 * Copyright (C) 2025 Michael N. Lipp 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <https://www.gnu.org/licenses/>. 017 */ 018 019package org.jdrupes.builder.core; 020 021import java.io.IOException; 022import java.io.InputStream; 023import java.io.OutputStream; 024import java.nio.file.Files; 025import java.nio.file.Path; 026import java.time.Instant; 027import java.util.Objects; 028import java.util.Optional; 029import org.jdrupes.builder.api.ConfigurationException; 030import org.jdrupes.builder.api.FileResource; 031import org.jdrupes.builder.api.ResourceType; 032 033/// A resource that represents a file. 034/// 035public class DefaultFileResource extends ResourceObject 036 implements FileResource { 037 038 private final Path path; 039 040 /// Instantiates a new file resource. 041 /// 042 /// @param type the type 043 /// @param path the path 044 /// 045 @SuppressWarnings("PMD.ConstructorCallsOverridableMethod") 046 protected DefaultFileResource(ResourceType<? extends FileResource> type, 047 Path path) { 048 super(type); 049 if (!path.isAbsolute()) { 050 throw new ConfigurationException().message( 051 "Path must be absolute, is %s", path); 052 } 053 var relPath = Path.of("").toAbsolutePath().relativize(path); 054 name(relPath.equals(Path.of("")) ? "." : relPath.toString()); 055 this.path = path; 056 } 057 058 /// Path. 059 /// 060 /// @return the path 061 /// 062 @Override 063 public Path path() { 064 return path; 065 } 066 067 @Override 068 public Optional<Instant> asOf() { 069 if (!path.toFile().exists()) { 070 return Optional.empty(); 071 } 072 return Optional.of(Instant.ofEpochMilli(path.toFile().lastModified())); 073 } 074 075 @Override 076 public InputStream inputStream() throws IOException { 077 return Files.newInputStream(path); 078 } 079 080 @Override 081 public OutputStream outputStream() throws IOException { 082 return Files.newOutputStream(path); 083 } 084 085 @Override 086 public int hashCode() { 087 final int prime = 31; 088 int result = super.hashCode(); 089 result = prime * result + Objects.hash(path); 090 return result; 091 } 092 093 @Override 094 public boolean equals(Object obj) { 095 if (this == obj) { 096 return true; 097 } 098 if (!super.equals(obj)) { 099 return false; 100 } 101 return (obj instanceof FileResource other) 102 && Objects.equals(path, other.path()); 103 } 104}