1 /*
2 * Copyright (c) 2002-2025 Gargoyle Software Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 * https://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package org.htmlunit;
16
17 import java.io.ByteArrayInputStream;
18 import java.io.File;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.Serializable;
22 import java.nio.file.Files;
23
24 import org.apache.commons.io.FileUtils;
25 import org.apache.commons.lang3.ArrayUtils;
26
27 /**
28 * Wrapper for content downloaded from a remote server.
29 *
30 * @author Marc Guillemot
31 * @author Ronald Brill
32 */
33 public interface DownloadedContent extends Serializable {
34
35 /**
36 * Implementation keeping content in memory.
37 */
38 class InMemory implements DownloadedContent {
39 private final byte[] bytes_;
40
41 InMemory(final byte[] byteArray) {
42 if (byteArray == null) {
43 bytes_ = ArrayUtils.EMPTY_BYTE_ARRAY;
44 }
45 else {
46 bytes_ = byteArray;
47 }
48 }
49
50 @Override
51 public InputStream getInputStream() {
52 return new ByteArrayInputStream(bytes_);
53 }
54
55 @Override
56 public void cleanUp() {
57 // nothing to do
58 }
59
60 @Override
61 public boolean isEmpty() {
62 return length() == 0;
63 }
64
65 @Override
66 public long length() {
67 return bytes_.length;
68 }
69 }
70
71 /**
72 * Implementation keeping content on the file system.
73 */
74 class OnFile implements DownloadedContent {
75 private final File file_;
76 private final boolean temporary_;
77
78 /**
79 * @param file the file
80 * @param temporary if true, the file will be deleted when cleanUp() is called.
81 */
82 OnFile(final File file, final boolean temporary) {
83 file_ = file;
84 temporary_ = temporary;
85 }
86
87 @Override
88 public InputStream getInputStream() throws IOException {
89 return Files.newInputStream(file_.toPath());
90 }
91
92 @Override
93 public void cleanUp() {
94 if (temporary_) {
95 FileUtils.deleteQuietly(file_);
96 }
97 }
98
99 @Override
100 public boolean isEmpty() {
101 return false;
102 }
103
104 @Override
105 protected void finalize() throws Throwable {
106 super.finalize();
107 cleanUp();
108 }
109
110 @Override
111 public long length() {
112 if (file_ == null) {
113 return 0;
114 }
115 return file_.length();
116 }
117 }
118
119 /**
120 * Returns a new {@link InputStream} allowing to read the downloaded content.
121 * @return the InputStream
122 * @throws IOException in case of problem accessing the content
123 */
124 InputStream getInputStream() throws IOException;
125
126 /**
127 * Clean up resources associated to this content.
128 */
129 void cleanUp();
130
131 /**
132 * Returns true if the content is empty.
133 * @return true or false
134 */
135 boolean isEmpty();
136
137 /**
138 * Returns the number of bytes.
139 * @return the length
140 */
141 long length();
142 }