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 }