001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019
020 package org.apache.myfaces.tobago.validator;
021
022 import org.apache.myfaces.tobago.component.UIFileInput;
023 import org.apache.myfaces.tobago.util.MessageFactory;
024 import org.apache.myfaces.tobago.util.ContentType;
025 import org.apache.commons.fileupload.FileItem;
026
027 import javax.faces.validator.Validator;
028 import javax.faces.validator.ValidatorException;
029 import javax.faces.component.StateHolder;
030 import javax.faces.component.UIComponent;
031 import javax.faces.context.FacesContext;
032 import javax.faces.application.FacesMessage;
033 import java.util.Arrays;
034
035 /**
036 * <p><strong>FileItemValidator</strong> is a {@link Validator} that checks
037 * the FileItem in the value of the associated component.
038 */
039
040 @org.apache.myfaces.tobago.apt.annotation.Validator(id = FileItemValidator.VALIDATOR_ID)
041 public class FileItemValidator implements Validator, StateHolder {
042 public static final String VALIDATOR_ID = "org.apache.myfaces.tobago.FileItem";
043 public static final String SIZE_LIMIT_MESSAGE_ID = "org.apache.myfaces.tobago.FileItemValidator.SIZE_LIMIT";
044 public static final String CONTENT_TYPE_MESSAGE_ID = "org.apache.myfaces.tobago.FileItemValidator.CONTENT_TYPE";
045 private Integer maxSize = null;
046 private String[] contentType;
047 private boolean transientValue;
048
049 public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
050 if (value != null && component instanceof UIFileInput) {
051 FileItem file = (FileItem) value;
052 if (maxSize != null && file.getSize() > maxSize) {
053 Object[] args = {maxSize, component.getId()};
054 FacesMessage facesMessage = MessageFactory.createFacesMessage(context,
055 SIZE_LIMIT_MESSAGE_ID, FacesMessage.SEVERITY_ERROR, args);
056 throw new ValidatorException(facesMessage);
057 }
058 // Check only a valid file
059 if (file.getSize() > 0 && contentType != null && contentType.length > 0) {
060 boolean found = false;
061 for (String contentTypeStr : contentType) {
062 if (ContentType.valueOf(contentTypeStr).match(ContentType.valueOf(file.getContentType()))) {
063 found = true;
064 break;
065 }
066 }
067 if (!found) {
068 String message;
069 if (contentType.length == 1) {
070 message = contentType[0];
071 } else {
072 message = Arrays.toString(contentType);
073 }
074 Object[] args = {message, component.getId()};
075 FacesMessage facesMessage = MessageFactory.createFacesMessage(context,
076 CONTENT_TYPE_MESSAGE_ID, FacesMessage.SEVERITY_ERROR, args);
077 throw new ValidatorException(facesMessage);
078 }
079 }
080 }
081 }
082
083 public int getMaxSize() {
084 return maxSize;
085 }
086
087 public void setMaxSize(int maxSize) {
088 if (maxSize > 0) {
089 this.maxSize = maxSize;
090 }
091 }
092
093 public String[] getContentType() {
094 return contentType;
095 }
096
097 public void setContentType(String[] contentType) {
098 this.contentType = contentType;
099 }
100
101 public Object saveState(FacesContext context) {
102 Object[] values = new Object[2];
103 values[0] = maxSize;
104 values[1] = contentType;
105 return values;
106 }
107
108 public void restoreState(FacesContext context, Object state) {
109 Object[] values = (Object[]) state;
110 maxSize = (Integer) values[0];
111 contentType = (String[]) values[1];
112 }
113
114 public boolean isTransient() {
115 return transientValue;
116 }
117
118 public void setTransient(boolean newTransientValue) {
119 this.transientValue = newTransientValue;
120 }
121 }