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