View Javadoc
1   /*
2    * Copyright (c) 2002-2026 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.util;
16  
17  import java.io.File;
18  import java.io.IOException;
19  import java.io.ObjectInputStream;
20  import java.io.ObjectOutputStream;
21  import java.nio.charset.Charset;
22  
23  /**
24   * <span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span><br>
25   *
26   * A holder for a key/value pair that represents a file to upload.
27   *
28   * @author Brad Clarke
29   * @author David D. Kilzer
30   * @author Mike Bowler
31   * @author Ahmed Ashour
32   * @author Ronald Brill
33   * @author Michael Lueck
34   */
35  public class KeyDataPair extends NameValuePair {
36  
37      private final File fileObject_;
38      private final String fileName_;
39      private final String mimeType_;
40      private transient Charset charset_;
41      private byte[] data_;
42  
43      /**
44       * Creates an instance.
45       *
46       * @param key the key
47       * @param file the file
48       * @param fileName the name of the file
49       * @param mimeType the MIME type
50       * @param charset the charset encoding name
51       */
52      public KeyDataPair(final String key, final File file, final String fileName,
53              final String mimeType, final String charset) {
54          this(key, file, fileName, mimeType, Charset.forName(charset));
55      }
56  
57      /**
58       * Creates an instance.
59       *
60       * @param key the key
61       * @param file the file
62       * @param fileName the name of the file
63       * @param mimeType the MIME type
64       * @param charset the charset encoding
65       */
66      public KeyDataPair(final String key, final File file, final String fileName,
67              final String mimeType, final Charset charset) {
68          this(key,
69                (file == null) ? "" : file.getName(),
70                (file != null && file.exists()) ? file : null,
71                fileName,
72                mimeType,
73                charset,
74                null);
75      }
76  
77      /**
78       * Private constructor setting all fields directly.
79       *
80       * @param name passed as the name to the super constructor
81       * @param value passed as the value to the super constructor
82       * @param file the file, may be {@code null}
83       * @param fileName the filename, may be {@code null}
84       * @param mimeType the MIME type, may be {@code null}
85       * @param charset the charset, may be {@code null}
86       * @param data the in-memory file data, may be {@code null}
87       */
88      private KeyDataPair(final String name, final String value, final File file,
89                final String fileName, final String mimeType, final Charset charset,
90                final byte[] data) {
91          super(name, value);
92  
93          fileObject_ = file;
94          fileName_ = fileName;
95  
96          mimeType_ = mimeType;
97          charset_ = charset;
98  
99          data_ = data;
100     }
101 
102     /**
103      * {@inheritDoc}
104      */
105     @Override
106     @SuppressWarnings("PMD.UselessOverridingMethod")
107     public boolean equals(final Object object) {
108         // this is overwritten to make FindBugs happy
109         // and to make it clear, that we really want to have
110         // the same equals semantic like our parent class
111         return super.equals(object);
112     }
113 
114     /**
115      * {@inheritDoc}
116      */
117     @Override
118     @SuppressWarnings("PMD.UselessOverridingMethod")
119     public int hashCode() {
120         // this is overwritten to make FindBugs happy
121         // and to make it clear, that we really want to have
122         // the same hashCode as our parent class
123         return super.hashCode();
124     }
125 
126     /**
127      * Returns the {@link File} object if the file exists, otherwise {@code null}.
128      *
129      * @return the file, or {@code null} if it does not exist
130      */
131     public File getFile() {
132         return fileObject_;
133     }
134 
135     /**
136      * Returns the file name.
137      *
138      * @return the file name
139      */
140     public String getFileName() {
141         return fileName_;
142     }
143 
144     /**
145      * Returns the charset encoding for this file upload.
146      *
147      * @return the charset
148      */
149     public Charset getCharset() {
150         return charset_;
151     }
152 
153     /**
154      * Returns the MIME type for this file upload.
155      *
156      * @return the MIME type
157      */
158     public String getMimeType() {
159         return mimeType_;
160     }
161 
162     /**
163      * Returns the in-memory data assigned to this file value,
164      * or {@code null} if the actual file content should be used.
165      *
166      * @return the in-memory data, or {@code null}
167      */
168     public byte[] getData() {
169         return data_;
170     }
171 
172     /**
173      * Sets the in-memory data for this file value.
174      * If not set, the file content will be used.
175      *
176      * @param data the byte array with file data
177      */
178     public void setData(final byte[] data) {
179         data_ = data;
180     }
181 
182     private void writeObject(final ObjectOutputStream oos) throws IOException {
183         oos.defaultWriteObject();
184         oos.writeObject(charset_ == null ? null : charset_.name());
185     }
186 
187     private void readObject(final ObjectInputStream ois) throws ClassNotFoundException, IOException {
188         ois.defaultReadObject();
189         final String charsetName = (String) ois.readObject();
190         if (charsetName != null) {
191             charset_ = Charset.forName(charsetName);
192         }
193     }
194 
195     /**
196      * {@inheritDoc}
197      *
198      * Specialization of the inherited method that copies all fields
199      * and ensures the value in the base class is not {@code null}.
200      */
201     @Override
202     public KeyDataPair normalized() {
203         return new KeyDataPair(
204             this.getName(),
205             this.getValue(),
206             this.fileObject_,
207             this.fileName_,
208             this.mimeType_,
209             this.charset_,
210             this.data_);
211     }
212 }