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.myfaces.tobago.component.UIFileInput;
021    import org.apache.myfaces.tobago.util.MessageFactory;
022    import org.apache.myfaces.tobago.util.ContentType;
023    import org.apache.commons.fileupload.FileItem;
024    
025    import javax.faces.validator.Validator;
026    import javax.faces.validator.ValidatorException;
027    import javax.faces.component.StateHolder;
028    import javax.faces.component.UIComponent;
029    import javax.faces.context.FacesContext;
030    import javax.faces.application.FacesMessage;
031    
032    /*
033     * Date: Oct 30, 2006
034     * Time: 9:59:13 PM
035     */
036    
037    /**
038     * <p><strong>FileItemValidator</strong> is a {@link Validator} that checks
039     * the FileItem in the value of the associated component.
040     */
041    
042    @org.apache.myfaces.tobago.apt.annotation.Validator(id = FileItemValidator.VALIDATOR_ID)
043    public class FileItemValidator implements Validator, StateHolder {
044      public static final String VALIDATOR_ID = "org.apache.myfaces.tobago.FileItem";
045      public static final String SIZE_LIMIT_MESSAGE_ID = "org.apache.myfaces.tobago.FileItemValidator.SIZE_LIMIT";
046      public static final String CONTENT_TYPE_MESSAGE_ID = "org.apache.myfaces.tobago.FileItemValidator.CONTENT_TYPE";
047      private Integer maxSize;
048      private String contentType;
049      private boolean transientValue;
050    
051      public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
052        if (value != null && component instanceof UIFileInput) {
053          FileItem file = (FileItem) value;
054          if (maxSize != null && file.getSize() > maxSize) {
055            Object[] args = {maxSize,  component.getId()};
056            FacesMessage facesMessage = MessageFactory.createFacesMessage(context,
057                SIZE_LIMIT_MESSAGE_ID, FacesMessage.SEVERITY_ERROR, args);
058            throw new ValidatorException(facesMessage);
059          }
060          // Check only a valid file
061          if (file.getSize() > 0 && contentType != null
062              && !ContentType.valueOf(contentType).match(ContentType.valueOf(file.getContentType()))) {
063            ContentType expectedContentType = ContentType.valueOf(contentType);
064            Object [] args = {expectedContentType, component.getId()};
065            FacesMessage facesMessage = MessageFactory.createFacesMessage(context,
066                CONTENT_TYPE_MESSAGE_ID, FacesMessage.SEVERITY_ERROR, args);
067            throw new ValidatorException(facesMessage);
068          }
069        }
070      }
071    
072      public int getMaxSize() {
073        return maxSize;
074      }
075    
076      public void setMaxSize(int maxSize) {
077        if (maxSize > 0) {
078          this.maxSize = maxSize;
079        }
080      }
081    
082      public String getContentType() {
083        return contentType;
084      }
085    
086      public void setContentType(String contentType) {
087        this.contentType = contentType;
088      }
089    
090      public Object saveState(FacesContext context) {
091        Object[] values = new Object[2];
092        values[0] = maxSize;
093        values[1] = contentType;
094        return values;
095      }
096    
097      public void restoreState(FacesContext context, Object state) {
098        Object[] values = (Object[]) state;
099        maxSize = (Integer) values[0];
100        contentType = (String) values[1];
101      }
102    
103      public boolean isTransient() {
104        return transientValue;
105      }
106    
107      public void setTransient(boolean newTransientValue) {
108        this.transientValue = newTransientValue;
109      }
110    }