View Javadoc

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 }