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 org.jdrupes.builder.api.BuildException; 029import org.jdrupes.builder.api.FileResource; 030import org.jdrupes.builder.api.ResourceType; 031 032/// A resource that represents a file. 033/// 034public class DefaultFileResource extends ResourceObject 035 implements FileResource { 036 037 private final Path path; 038 039 /// Instantiates a new file resource. 040 /// 041 /// @param type the type 042 /// @param path the path 043 /// 044 @SuppressWarnings("PMD.ConstructorCallsOverridableMethod") 045 protected DefaultFileResource(ResourceType<? extends FileResource> type, 046 Path path) { 047 super(type); 048 if (!path.isAbsolute()) { 049 throw new BuildException("Path must be absolute, is %s", path); 050 } 051 var relPath = Path.of("").toAbsolutePath().relativize(path); 052 name(relPath.equals(Path.of("")) ? "." : relPath.toString()); 053 this.path = path; 054 } 055 056 /// Path. 057 /// 058 /// @return the path 059 /// 060 @Override 061 public Path path() { 062 return path; 063 } 064 065 @Override 066 public Instant asOf() { 067 if (!path.toFile().exists()) { 068 return Instant.MIN; 069 } 070 return Instant.ofEpochMilli(path.toFile().lastModified()); 071 } 072 073 @Override 074 public InputStream inputStream() throws IOException { 075 return Files.newInputStream(path); 076 } 077 078 @Override 079 public OutputStream outputStream() throws IOException { 080 return Files.newOutputStream(path); 081 } 082 083 @Override 084 public int hashCode() { 085 final int prime = 31; 086 int result = super.hashCode(); 087 result = prime * result + Objects.hash(path); 088 return result; 089 } 090 091 @Override 092 public boolean equals(Object obj) { 093 if (this == obj) { 094 return true; 095 } 096 if (!super.equals(obj)) { 097 return false; 098 } 099 return (obj instanceof FileResource other) 100 && Objects.equals(path, other.path()); 101 } 102}