001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.cp; 014 015import static org.apache.juneau.common.internal.ArgUtils.*; 016import static org.apache.juneau.common.internal.IOUtils.*; 017 018import java.io.*; 019import java.nio.file.*; 020 021/** 022 * Identifies a file located either on the classpath or file system. 023 * 024 * Used to encapsulate basic resolution and retrieval of files regardless of where they are located. 025 * 026 * <h5 class='section'>See Also:</h5><ul> 027 * </ul> 028 */ 029public class LocalFile { 030 031 private final Class<?> clazz; 032 private final String clazzPath; 033 private final Path path; 034 private final String name; 035 private byte[] cache; 036 037 /** 038 * Constructor for classpath file. 039 * 040 * @param clazz The class used to retrieve resources. Must not be <jk>null</jk>. 041 * @param clazzPath The path relative to the class. Must be a non-null normalized relative path. 042 */ 043 public LocalFile(Class<?> clazz, String clazzPath) { 044 this.clazz = assertArgNotNull("clazz", clazz); 045 this.clazzPath = assertArgNotNull("clazzPath", clazzPath); 046 this.path = null; 047 int i = clazzPath.lastIndexOf('/'); 048 this.name = i == -1 ? clazzPath : clazzPath.substring(i+1); 049 } 050 051 /** 052 * Constructor for file system file. 053 * 054 * @param path Filesystem file location. Must not be <jk>null</jk>. 055 */ 056 public LocalFile(Path path) { 057 this.clazz = null; 058 this.clazzPath = null; 059 this.path = assertArgNotNull("path", path); 060 this.name = path.getFileName().toString(); 061 } 062 063 /** 064 * Returns the contents of this file. 065 * 066 * @return An input stream of the contents of this file. 067 * @throws IOException If file could not be read. 068 */ 069 public InputStream read() throws IOException { 070 synchronized(this) { 071 if (cache != null) 072 return new ByteArrayInputStream(cache); 073 } 074 if (clazz != null) 075 return clazz.getResourceAsStream(clazzPath); 076 return Files.newInputStream(path); 077 } 078 079 /** 080 * Returns the size of this file. 081 * 082 * @return The size of this file in bytes, or <c>-1</c> if not known. 083 * @throws IOException If file size could not be determined. 084 */ 085 public long size() throws IOException { 086 return (path == null ? -1 : Files.size(path)); 087 } 088 089 /** 090 * Caches the contents of this file into an internal byte array for quick future retrieval. 091 * 092 * @return This object. 093 * @throws IOException If file could not be read. 094 */ 095 public LocalFile cache() throws IOException { 096 synchronized(this) { 097 this.cache = readBytes(read()); 098 } 099 return this; 100 } 101 102 /** 103 * Returns the name of this file. 104 * 105 * @return The name of this file. 106 */ 107 public String getName() { 108 return name; 109 } 110}