1 /*
2 * Copyright (c) 2002-2008 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 * http://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 com.gargoylesoftware.htmlunit.html;
16
17 import java.io.File;
18 import java.net.URI;
19 import java.net.URISyntaxException;
20 import java.util.Map;
21
22 import org.apache.commons.httpclient.NameValuePair;
23 import org.apache.commons.lang.StringUtils;
24
25 import com.gargoylesoftware.htmlunit.KeyDataPair;
26 import com.gargoylesoftware.htmlunit.SgmlPage;
27
28 /**
29 * Wrapper for the HTML element "input".
30 *
31 * @version $Revision: 3158 $
32 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
33 * @author <a href="mailto:cse@dynabean.de">Christian Sell</a>
34 * @author Daniel Gredler
35 * @author Ahmed Ashour
36 * @author Marc Guillemot
37 */
38 public class HtmlFileInput extends HtmlInput {
39
40 private static final long serialVersionUID = 7925479292349207154L;
41 private String contentType_;
42 private byte[] data_;
43
44 /**
45 * Creates an instance.
46 *
47 * @param namespaceURI the URI that identifies an XML namespace
48 * @param qualifiedName the qualified name of the element type to instantiate
49 * @param page the page that contains this element
50 * @param attributes the initial attributes
51 */
52 HtmlFileInput(final String namespaceURI, final String qualifiedName, final SgmlPage page,
53 final Map<String, DomAttr> attributes) {
54 super(namespaceURI, qualifiedName, page, attributes);
55 setAttributeValue("value", "");
56 if (page.getWebClient().getBrowserVersion().isIE()) {
57 setDefaultValue("");
58 }
59 }
60
61 /**
62 * Returns in-memory data assigned to element.
63 * @return <code>null</code> if {@link #setData(byte[])} hasn't be used.
64 */
65 public final byte[] getData() {
66 return data_;
67 }
68
69 /**
70 * Assigns data to element.
71 * During submission instead of loading data from file, the data is read from
72 * in-memory byte array.
73 * @param data byte array containing file data
74 */
75 public final void setData(final byte[] data) {
76 data_ = data;
77 }
78
79 /**
80 * {@inheritDoc}
81 */
82 @Override
83 public NameValuePair[] getSubmitKeyValuePairs() {
84 String value = getValueAttribute();
85
86 if (StringUtils.isEmpty(value)) {
87 return new NameValuePair[] {new KeyDataPair(getNameAttribute(), new File(""), null, null)};
88 }
89
90 File file = null;
91 // to tolerate file://
92 if (value.startsWith("file:/")) {
93 if (value.startsWith("file://") && !value.startsWith("file:///")) {
94 value = "file:///" + value.substring(7);
95 }
96 try {
97 file = new File(new URI(value));
98 }
99 catch (final URISyntaxException e) {
100 // nothing here
101 }
102 }
103
104 if (file == null) {
105 file = new File(value);
106 }
107
108 // contentType and charset are determined from browser and page
109 // perhaps it could be interesting to have setters for it in this class
110 // to give finer control to user
111 final String contentType;
112 if (contentType_ == null) {
113 contentType = getPage().getWebClient().guessContentType(file);
114 }
115 else {
116 contentType = contentType_;
117 }
118 final String charset = getPage().getPageEncoding();
119 final KeyDataPair keyDataPair = new KeyDataPair(getNameAttribute(), file, contentType, charset);
120 keyDataPair.setData(data_);
121 return new NameValuePair[] {keyDataPair};
122 }
123
124 /**
125 * {@inheritDoc} This method <b>does nothing</b> for file input elements.
126 * @see SubmittableElement#reset()
127 */
128 @Override
129 public void reset() {
130 // Empty.
131 }
132
133 /**
134 * {@inheritDoc} Overridden so that this does not set the value attribute when emulating
135 * Netscape browsers.
136 * @see HtmlInput#setDefaultValue(String)
137 */
138 @Override
139 public void setDefaultValue(final String defaultValue) {
140 setDefaultValue(defaultValue, false);
141 }
142
143 /**
144 * Sets the content type value that should be send together with the uploaded file.
145 * If content type is not explicitly set, HtmlUnit will try to guess it from the file content.
146 * @param contentType the content type, <code>null</code> resets it
147 */
148 public void setContentType(final String contentType) {
149 contentType_ = contentType;
150 }
151
152 /**
153 * Gets the content type that should be send together with the uploaded file.
154 * @return the content type, <code>null</code> if this has not been explicitly set
155 * and should be guessed from file content.
156 */
157 public String getContentType() {
158 return contentType_;
159 }
160 }