001: /**
002: * Copyright 2006 Webmedia Group Ltd.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: **/package org.araneaframework.uilib.form.control;
016:
017: import java.util.List;
018: import org.apache.commons.fileupload.FileItem;
019: import org.araneaframework.core.AraneaRuntimeException;
020: import org.araneaframework.core.NoSuchNarrowableException;
021: import org.araneaframework.framework.FileUploadContext;
022: import org.araneaframework.http.FileUploadInputExtension;
023: import org.araneaframework.http.HttpInputData;
024: import org.araneaframework.uilib.support.FileInfo;
025: import org.araneaframework.uilib.support.UiLibMessages;
026: import org.araneaframework.uilib.util.MessageUtil;
027:
028: /**
029: * This class represents an HTML form file upload control.
030: *
031: * @author Jevgeni Kabanov (ekabanov <i>at</i> araneaframework <i>dot</i> org)
032: *
033: */
034: public class FileUploadControl extends BaseControl {
035: protected List permittedMimeFileTypes;
036:
037: protected boolean uploadSucceeded = true;
038: protected boolean mimeTypePermitted = true;
039:
040: public boolean isRead() {
041: return innerData != null;
042: }
043:
044: /**
045: * Sets the MIME file types that will be permitted,
046: *
047: * @param permittedMimeFileTypes
048: * the MIME file types that will be permitted.
049: */
050: public void setPermittedMimeFileTypes(List permittedMimeFileTypes) {
051: this .permittedMimeFileTypes = permittedMimeFileTypes;
052: }
053:
054: /**
055: * Returns "FileInfo".
056: *
057: * @return "FileInfo".
058: */
059: public String getRawValueType() {
060: return "FileInfo";
061: }
062:
063: // *********************************************************************
064: // * INTERNAL METHODS
065: // *********************************************************************
066:
067: /**
068: * Empty.
069: */
070: protected void prepareResponse() {
071: // There is no response for file upload control.
072: }
073:
074: /**
075: * Reads the {@link FileInfo}data from request {@link HttpInputData}.
076: */
077: protected void readFromRequest(HttpInputData request) {
078: FileUploadInputExtension fileUpload = getFileUploadInputExtension(request);
079: // this is acceptable, see comments in getFileUploadInputExtension()
080: if (fileUpload == null) {
081: return;
082: }
083:
084: // FIXME: unfortunately this conditional code is unreachable because when request
085: // parsing fails transaction id is usually not set (inconsistent) and update() is never called
086: uploadSucceeded = fileUpload.uploadSucceeded();
087: if (!uploadSucceeded) {
088: return;
089: }
090:
091: if (fileUpload.getUploadedFile(getScope().toString()) != null) {
092: FileItem file = fileUpload.getUploadedFile(getScope()
093: .toString());
094: String mimeType = file.getContentType();
095:
096: mimeTypePermitted = permittedMimeFileTypes == null
097: || permittedMimeFileTypes.contains(mimeType);
098:
099: if (mimeTypePermitted) {
100: innerData = new FileInfo(file);
101: }
102: }
103: }
104:
105: private FileUploadInputExtension getFileUploadInputExtension(
106: HttpInputData request) {
107: if (getEnvironment().getEntry(FileUploadContext.class) == null)
108: throw new AraneaRuntimeException(
109: "It seems that attempt was made to use FileUploadControl, but upload filter is not present.");
110:
111: FileUploadInputExtension fileUpload = null;
112: // Motivation for try: when one opens fileuploaddemo in new window (cloning!), exception occurs b/c
113: // FileUploadInputExtension extension does not exist in InputData which is
114: // extended only when request is multipart, while cloning filter always sends ordinary GET.
115: try {
116: fileUpload = (FileUploadInputExtension) request
117: .narrow(FileUploadInputExtension.class);
118: } catch (NoSuchNarrowableException e) {
119: // If no fileupload extension is present and fileupload filter is enabled, control should
120: // just sit there and be beautiful, otherwise just return null
121: }
122: return fileUpload;
123: }
124:
125: public void convert() {
126: value = innerData;
127:
128: if (!uploadSucceeded) {
129: Long sizeLimit = ((FileUploadContext) getEnvironment()
130: .getEntry(FileUploadContext.class))
131: .getFileSizeLimit();
132: addError(MessageUtil.localizeAndFormat(
133: UiLibMessages.FILE_UPLOAD_FAILED, sizeLimit
134: .toString(), getEnvironment()));
135: return;
136: }
137: }
138:
139: public void validate() {
140: boolean fieldFilled = false;
141: FileInfo info = (FileInfo) innerData;
142: fieldFilled = info != null && info.getSize() > 0
143: && info.getOriginalFilename() != null
144: && !info.getOriginalFilename().trim().equals("");
145:
146: if ((isMandatory() && !isRead())
147: || (isMandatory() && !fieldFilled)) {
148: addError(MessageUtil.localizeAndFormat(
149: UiLibMessages.MANDATORY_FIELD, MessageUtil
150: .localize(getLabel(), getEnvironment()),
151: getEnvironment()));
152: }
153: if (!mimeTypePermitted) {
154: addError(MessageUtil.localizeAndFormat(
155: UiLibMessages.FORBIDDEN_MIME_TYPE, MessageUtil
156: .localize(getLabel(), getEnvironment()),
157: getEnvironment()));
158: }
159: }
160:
161: /**
162: * Returns {@link ViewModel}.
163: *
164: * @return {@link ViewModel}.
165: */
166: public Object getViewModel() {
167: return new ViewModel();
168: }
169:
170: // *********************************************************************
171: // * VIEW MODEL
172: // *********************************************************************
173:
174: /**
175: * @author Jevgeni Kabanov (ekabanov <i>at</i> araneaframework <i>dot</i> org)
176: */
177: public class ViewModel extends BaseControl.ViewModel {
178:
179: private List permittedMimeFileTypes;
180:
181: /**
182: * Takes an outer class snapshot.
183: */
184: public ViewModel() {
185: this .permittedMimeFileTypes = FileUploadControl.this .permittedMimeFileTypes;
186: }
187:
188: /**
189: * Returns the MIME file types that will be permitted,
190: *
191: * @return the MIME file types that will be permitted.
192: */
193: public List getPermittedMimeFileTypes() {
194: return permittedMimeFileTypes;
195: }
196: }
197: }
|