View Javadoc
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.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
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 plain properties.
79       *
80       * @param name will passed as name to the super constructor
81       * @param value will be passed as value to the super constructor
82       * @param file the file, may be null
83       * @param fileName the filename, may be null
84       * @param mimeType the mimetype, may be null
85       * @param charset the charset, may be null
86       */
87      private KeyDataPair(final String name, final String value, final File file,
88                final String fileName, final String mimeType, final Charset charset,
89                final byte[] data) {
90          super(name, value);
91  
92          fileObject_ = file;
93          fileName_ = fileName;
94  
95          mimeType_ = mimeType;
96          charset_ = charset;
97  
98          data_ = data;
99      }
100 
101     /**
102      * {@inheritDoc}
103      */
104     @Override
105     @SuppressWarnings("PMD.UselessOverridingMethod")
106     public boolean equals(final Object object) {
107         // this is overwritten to make FindBugs happy
108         // and to make it clear, that we really want to have
109         // the same equals semantic like our parent class
110         return super.equals(object);
111     }
112 
113     /**
114      * {@inheritDoc}
115      */
116     @Override
117     @SuppressWarnings("PMD.UselessOverridingMethod")
118     public int hashCode() {
119         // this is overwritten to make FindBugs happy
120         // and to make it clear, that we really want to have
121         // the same hashCode like our parent class
122         return super.hashCode();
123     }
124 
125     /**
126      * @return the {@link File} object if the file exists, else {@code null}
127      */
128     public File getFile() {
129         return fileObject_;
130     }
131 
132     /**
133      * @return the fileName
134      */
135     public String getFileName() {
136         return fileName_;
137     }
138 
139     /**
140      * Gets the charset encoding for this file upload.
141      * @return the charset
142      */
143     public Charset getCharset() {
144         return charset_;
145     }
146 
147     /**
148      * Gets the MIME type for this file upload.
149      * @return the MIME type
150      */
151     public String getMimeType() {
152         return mimeType_;
153     }
154 
155     /**
156      * Gets in-memory data assigned to file value.
157      * @return {@code null} if the file content should be used.
158      */
159     public byte[] getData() {
160         return data_;
161     }
162 
163     /**
164      * Sets file value data. If nothing is set, the file content will be used.
165      * @param data byte array with file data.
166      */
167     public void setData(final byte[] data) {
168         data_ = data;
169     }
170 
171     private void writeObject(final ObjectOutputStream oos) throws IOException {
172         oos.defaultWriteObject();
173         oos.writeObject(charset_ == null ? null : charset_.name());
174     }
175 
176     private void readObject(final ObjectInputStream ois) throws ClassNotFoundException, IOException {
177         ois.defaultReadObject();
178         final String charsetName = (String) ois.readObject();
179         if (charsetName != null) {
180             charset_ = Charset.forName(charsetName);
181         }
182     }
183 
184     /**
185      * {@inheritDoc}
186      *
187      * Specialization of inherited method which will copy all fields
188      * and make sure that the value in the base class is not null, by calling
189      * the constructor with the current value
190      */
191     @Override
192     public KeyDataPair normalized() {
193         return new KeyDataPair(
194             this.getName(),
195             this.getValue(),
196             this.fileObject_,
197             this.fileName_,
198             this.mimeType_,
199             this.charset_,
200             this.data_);
201     }
202 }