/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.citrus.service.form.impl.validation; import static com.alibaba.citrus.util.ArrayUtil.*; import static com.alibaba.citrus.util.Assert.*; import static com.alibaba.citrus.util.CollectionUtil.*; import static com.alibaba.citrus.util.StringUtil.*; import java.util.List; import com.alibaba.citrus.service.form.support.AbstractValidator; import com.alibaba.citrus.service.form.support.AbstractValidatorDefinitionParser; import com.alibaba.citrus.util.FileUtil; import com.alibaba.citrus.util.HumanReadableSize; import org.apache.commons.fileupload.FileItem; /** * 验证上传文件的validator。 * * @author Michael Zhou */ public class UploadedFileValidator extends AbstractValidator { private String[] contentTypes; private String[] extensions; private HumanReadableSize minSize = new HumanReadableSize(-1); private HumanReadableSize maxSize = new HumanReadableSize(-1); /** 取得上传文件的contentTypes。 */ public String[] getContentType() { return contentTypes; } /** 设置上传文件的contentType。 */ public void setContentType(String[] contentTypes) { this.contentTypes = normalizeStrings(contentTypes, 0); } /** 取得上传文件的文件名后缀。 */ public String[] getExtension() { return extensions; } /** 设置上传文件的文件名后缀。 */ public void setExtension(String[] extensions) { this.extensions = normalizeStrings(extensions, 1); } /** * 取得最小尺寸。 * <p> * 支持K/M/G/T等。 * </p> */ public HumanReadableSize getMinSize() { return minSize; } /** * 设置最小尺寸。 * <p> * 支持K/M/G/T等。 * </p> */ public void setMinSize(HumanReadableSize minSize) { this.minSize = assertNotNull(minSize, "minSize"); } /** * 取得最大尺寸。 * <p> * 支持K/M/G/T等。 * </p> */ public HumanReadableSize getMaxSize() { return maxSize; } /** * 设置最大尺寸。 * <p> * 支持K/M/G/T等。 * </p> */ public void setMaxSize(HumanReadableSize maxSize) { this.maxSize = assertNotNull(maxSize, "maxSize"); } /** 验证一个字段。 */ public boolean validate(Context context) { long minSize = this.minSize.getValue(); long maxSize = this.maxSize.getValue(); if (isEmptyArray(contentTypes) && isEmptyArray(extensions) && maxSize <= 0 && minSize < 0) { return true; } FileItem[] fileItems = context.getField().getFileItems(); // 假如不存在fileItems,也通过验证。用required-validator来确保fileItem有值。 if (isEmptyArray(fileItems)) { return true; } for (FileItem fileItem : fileItems) { if (fileItem == null) { continue; // 忽略空item } // 检查size limit。 if (minSize >= 0 && fileItem.getSize() < minSize) { return false; } if (maxSize >= 0 && fileItem.getSize() > maxSize) { return false; } // 检查content type。 if (!isEmptyArray(contentTypes)) { String fileContentType = normalizeContentType(fileItem.getContentType()); if (fileContentType == null) { return false; } boolean matched = false; for (String expectedContentType : contentTypes) { if (fileContentType.startsWith(expectedContentType)) { matched = true; break; } } if (!matched) { return false; } } // 检查extension。 if (!isEmptyArray(extensions)) { // 未指定文件名 - 返回null // 文件名没有后缀 - 返回字符串“null” // 后缀被规格化为小写字母 String ext = FileUtil.getExtension(fileItem.getName(), "null", true); if (ext == null) { return false; } boolean matched = false; for (String expectedExtension : extensions) { if (expectedExtension.equals(ext)) { matched = true; break; } } if (!matched) { return false; } } } return true; } private String[] normalizeStrings(String[] strs, int type) { if (isEmptyArray(strs)) { return null; } List<String> strList = createLinkedList(); for (String str : strs) { switch (type) { case 0: str = normalizeContentType(str); break; case 1: str = FileUtil.normalizeExtension(str); break; default: unreachableCode(); } if (str != null) { strList.add(str); } } if (strList.isEmpty()) { return null; } else { return strList.toArray(new String[strList.size()]); } } private String normalizeContentType(String contentType) { contentType = trimToNull(contentType); if (contentType != null) { contentType = contentType.toLowerCase(); } return contentType; } public static class DefinitionParser extends AbstractValidatorDefinitionParser<UploadedFileValidator> { } }