001// Generated by delombok at Mon Jan 02 16:27:27 UTC 2023 002package io.cui.tools.io; 003 004import static io.cui.tools.base.Preconditions.checkState; 005import static io.cui.tools.string.MoreStrings.isEmpty; 006import static io.cui.tools.string.MoreStrings.requireNotEmpty; 007import static java.util.Objects.requireNonNull; 008import java.io.IOException; 009import java.io.InputStream; 010import java.net.URL; 011import java.util.Optional; 012import io.cui.tools.lang.SecuritySupport; 013import io.cui.tools.logging.CuiLogger; 014 015/** 016 * Variant of {@link FileLoader} that loads files from the classpath. 017 * 018 * @author Oliver Wolff 019 */ 020public class ClassPathLoader implements FileLoader { 021 private static final long serialVersionUID = 9140071059594577808L; 022 private static final CuiLogger log = new CuiLogger(ClassPathLoader.class); 023 private final String normalizedPathName; 024 private final String givenPathName; 025 private final StructuredFilename fileName; 026 private URL url; 027 028 /** 029 * @param pathName must not be null nor empty, may start with the prefix 030 * {@link FileTypePrefix#CLASSPATH} but not with 031 * {@link FileTypePrefix#FILE} and contain at least one character despite the prefix. 032 * On all other cases a {@link IllegalArgumentException} will be 033 * thrown. 034 */ 035 public ClassPathLoader(final String pathName) { 036 requireNonNull(pathName); 037 givenPathName = pathName; 038 normalizedPathName = checkClasspathName(pathName); 039 fileName = new StructuredFilename(FilenameUtils.getName(normalizedPathName)); 040 } 041 042 /** 043 * Checks and modifies a given pathName 044 * 045 * @param pathName must not be null nor empty, may start with the prefix 046 * {@link FileTypePrefix#CLASSPATH} but not with 047 * {@link FileTypePrefix#FILE} and contain at least one character despite 048 * the prefix. On all other cases a {@link IllegalArgumentException} will be 049 * thrown. 050 * @return the normalized pathname without prefix but with a leading '/' 051 */ 052 static String checkClasspathName(final String pathName) { 053 requireNotEmpty(pathName); 054 if (FileTypePrefix.FILE.is(pathName)) { 055 throw new IllegalArgumentException("Invalid path name, must start not start with " + FileTypePrefix.FILE + " but was: " + pathName); 056 } 057 String newPathName = pathName; 058 if (FileTypePrefix.CLASSPATH.is(pathName)) { 059 newPathName = FileTypePrefix.CLASSPATH.removePrefix(pathName); 060 } 061 if (isEmpty(newPathName)) { 062 throw new IllegalArgumentException("Filename " + pathName + " is invalid"); 063 } 064 if (newPathName.indexOf('/') != 0) { 065 newPathName = '/' + newPathName; 066 } 067 return newPathName; 068 } 069 070 @Override 071 public boolean isReadable() { 072 return null != getURL(); 073 } 074 075 @Override 076 public InputStream inputStream() { 077 checkState(isReadable(), "Resource \'{}\' is not readable", givenPathName); 078 try { 079 return getURL().openStream(); 080 } catch (IOException e) { 081 throw new IllegalStateException("Unable to load classpath file for " + givenPathName, e); 082 } 083 } 084 085 @Override 086 public boolean isFilesystemLoader() { 087 return false; 088 } 089 090 @Override 091 public URL getURL() { 092 if (null == url) { 093 url = resolveUrl(normalizedPathName); 094 } 095 return url; 096 } 097 098 private static URL resolveUrl(String path) { 099 log.debug("Resolving URL for \'{}\'", path); 100 URL url = ClassPathLoader.class.getResource(path); 101 if (null != url) { 102 log.debug("Resolved \'{}\' from ClassPathLoader.class", path); 103 return url; 104 } 105 Optional<ClassLoader> loader = SecuritySupport.getContextClassLoader(); 106 if (loader.isPresent()) { 107 url = loader.get().getResource(path); 108 if (null != url) { 109 log.debug("Resolved \'{}\' from ContextClassLoader", path); 110 return url; 111 } 112 } 113 log.warn("Unable to resolve \'{}\' from classpath", path); 114 return null; 115 } 116 117 @java.lang.Override 118 @java.lang.SuppressWarnings("all") 119 @lombok.Generated 120 public boolean equals(final java.lang.Object o) { 121 if (o == this) return true; 122 if (!(o instanceof ClassPathLoader)) return false; 123 final ClassPathLoader other = (ClassPathLoader) o; 124 if (!other.canEqual((java.lang.Object) this)) return false; 125 final java.lang.Object this$normalizedPathName = this.normalizedPathName; 126 final java.lang.Object other$normalizedPathName = other.normalizedPathName; 127 if (this$normalizedPathName == null ? other$normalizedPathName != null : !this$normalizedPathName.equals(other$normalizedPathName)) return false; 128 return true; 129 } 130 131 @java.lang.SuppressWarnings("all") 132 @lombok.Generated 133 protected boolean canEqual(final java.lang.Object other) { 134 return other instanceof ClassPathLoader; 135 } 136 137 @java.lang.Override 138 @java.lang.SuppressWarnings("all") 139 @lombok.Generated 140 public int hashCode() { 141 final int PRIME = 59; 142 int result = 1; 143 final java.lang.Object $normalizedPathName = this.normalizedPathName; 144 result = result * PRIME + ($normalizedPathName == null ? 43 : $normalizedPathName.hashCode()); 145 return result; 146 } 147 148 @java.lang.Override 149 @java.lang.SuppressWarnings("all") 150 @lombok.Generated 151 public java.lang.String toString() { 152 return "ClassPathLoader(normalizedPathName=" + this.normalizedPathName + ", givenPathName=" + this.givenPathName + ", fileName=" + this.getFileName() + ", url=" + this.getURL() + ")"; 153 } 154 155 @java.lang.SuppressWarnings("all") 156 @lombok.Generated 157 public StructuredFilename getFileName() { 158 return this.fileName; 159 } 160}