1 package org.codehaus.plexus.components.io.resources;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import javax.annotation.Nonnull;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.net.URL;
27 import java.nio.file.Files;
28 import java.nio.file.attribute.FileTime;
29
30 import org.apache.commons.io.IOUtils;
31 import org.apache.commons.io.output.DeferredFileOutputStream;
32 import org.codehaus.plexus.components.io.attributes.AttributeUtils;
33 import org.codehaus.plexus.components.io.attributes.FileAttributes;
34 import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes;
35 import org.codehaus.plexus.components.io.functions.ContentSupplier;
36 import org.codehaus.plexus.components.io.functions.FileSupplier;
37 import org.codehaus.plexus.components.io.functions.InputStreamTransformer;
38 import org.codehaus.plexus.components.io.functions.ResourceAttributeSupplier;
39
40 import static java.util.Objects.requireNonNull;
41
42
43
44
45 public class PlexusIoFileResource extends AbstractPlexusIoResource implements ResourceAttributeSupplier, FileSupplier {
46
47 @Nonnull
48 private final File file;
49
50 @Nonnull
51 private final PlexusIoResourceAttributes attributes;
52
53 @Nonnull
54 private final FileAttributes fileAttributes;
55
56 private final ContentSupplier contentSupplier;
57
58 private final DeferredFileOutputStream dfos;
59
60 protected PlexusIoFileResource(@Nonnull File file, @Nonnull String name, @Nonnull PlexusIoResourceAttributes attrs)
61 throws IOException {
62 this(file, name, attrs, null, null);
63 }
64
65 PlexusIoFileResource(
66 @Nonnull final File file,
67 @Nonnull String name,
68 @Nonnull PlexusIoResourceAttributes attrs,
69 final ContentSupplier contentSupplier,
70 final InputStreamTransformer streamTransformer)
71 throws IOException {
72 this(file, name, attrs, new FileAttributes(file, true), contentSupplier, streamTransformer);
73 }
74
75 PlexusIoFileResource(
76 @Nonnull final File file,
77 @Nonnull String name,
78 @Nonnull PlexusIoResourceAttributes attrs,
79 @Nonnull FileAttributes fileAttributes,
80 final ContentSupplier contentSupplier,
81 final InputStreamTransformer streamTransformer)
82 throws IOException {
83 super(
84 name,
85 fileAttributes.getLastModifiedTime().toMillis(),
86 fileAttributes.getSize(),
87 fileAttributes.isRegularFile(),
88 fileAttributes.isDirectory(),
89 fileAttributes.isRegularFile()
90 || fileAttributes.isDirectory()
91 || fileAttributes.isSymbolicLink()
92 || fileAttributes.isOther());
93 this.file = file;
94 this.attributes = requireNonNull(attrs, "attributes is null for file " + file.getName());
95 this.fileAttributes = requireNonNull(fileAttributes, "fileAttributes is null for file " + file.getName());
96 this.contentSupplier = contentSupplier != null ? contentSupplier : getRootContentSupplier(file);
97
98 boolean hasTransformer = streamTransformer != null && streamTransformer != identityTransformer;
99 InputStreamTransformer transToUse = streamTransformer != null ? streamTransformer : identityTransformer;
100
101 dfos = hasTransformer && file.isFile() ? asDeferredStream(this.contentSupplier, transToUse, this) : null;
102 }
103
104 private static DeferredFileOutputStream asDeferredStream(
105 @Nonnull ContentSupplier supplier, @Nonnull InputStreamTransformer transToUse, PlexusIoResource resource)
106 throws IOException {
107 DeferredFileOutputStream dfos = DeferredFileOutputStream.builder()
108 .setThreshold(5000000)
109 .setPrefix("p-archiver")
110 .get();
111 try (InputStream inputStream = supplier.getContents();
112 InputStream transformed = transToUse.transform(resource, inputStream);
113 DeferredFileOutputStream closeable = dfos) {
114 IOUtils.copy(transformed, dfos);
115 }
116 return dfos;
117 }
118
119 private static ContentSupplier getRootContentSupplier(final File file) {
120 return () -> Files.newInputStream(file.toPath());
121 }
122
123 public static String getName(File file) {
124 return file.getPath().replace('\\', '/');
125 }
126
127
128
129
130 @Nonnull
131 public File getFile() {
132 return file;
133 }
134
135 @Nonnull
136 public InputStream getContents() throws IOException {
137 if (dfos == null) {
138 return contentSupplier.getContents();
139 }
140 if (dfos.isInMemory()) {
141 return new ByteArrayInputStream(dfos.getData());
142 } else {
143 return new FileInputStream(dfos.getFile()) {
144 @SuppressWarnings("ResultOfMethodCallIgnored")
145 @Override
146 public void close() throws IOException {
147 super.close();
148 dfos.getFile().delete();
149 }
150 };
151 }
152 }
153
154 @Nonnull
155 public URL getURL() throws IOException {
156 return getFile().toURI().toURL();
157 }
158
159 public long getSize() {
160 if (dfos == null) {
161 return fileAttributes.getSize();
162 }
163 if (dfos.isInMemory()) {
164 return dfos.getByteCount();
165 } else {
166 return dfos.getFile().length();
167 }
168 }
169
170 public boolean isDirectory() {
171 return fileAttributes.isDirectory();
172 }
173
174 public boolean isExisting() {
175 if (attributes instanceof FileAttributes) {
176 return true;
177 }
178 return getFile().exists();
179 }
180
181 public boolean isFile() {
182 return fileAttributes.isRegularFile();
183 }
184
185 @Nonnull
186 public PlexusIoResourceAttributes getAttributes() {
187 return attributes;
188 }
189
190 @Nonnull
191 public FileAttributes getFileAttributes() {
192 return fileAttributes;
193 }
194
195 public long getLastModified() {
196 FileTime lastModified = fileAttributes.getLastModifiedTime();
197 if (lastModified != null) {
198 return lastModified.toMillis();
199 }
200 return AttributeUtils.getLastModified(getFile());
201 }
202
203 @Override
204 public boolean isSymbolicLink() {
205 return getAttributes().isSymbolicLink();
206 }
207
208 protected DeferredFileOutputStream getDfos() {
209 return dfos;
210 }
211
212 private static final InputStreamTransformer identityTransformer =
213 AbstractPlexusIoResourceCollection.identityTransformer;
214 }