/*******************************************************************************
* Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. All rights reserved.
* This program and the accompanying materials are made available under the terms
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.tcf.te.ui.controls.validator;
import java.io.File;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
/**
* Input validator for files.
*/
public class FileNameValidator extends Validator {
// keys for info messages file
public static final String INFO_MISSING_FILE_NAME = "FileNameValidator_Information_MissingName"; //$NON-NLS-1$
// keys for error messages file
public static final String ERROR_INVALID_FILE_NAME = "FileNameValidator_Error_InvalidName"; //$NON-NLS-1$
public static final String ERROR_IS_DIRECTORY = "FileNameValidator_Error_IsDirectory"; //$NON-NLS-1$
public static final String ERROR_MUST_EXIST = "FileNameValidator_Error_MustExist"; //$NON-NLS-1$
public static final String ERROR_READ_ONLY = "FileNameValidator_Error_ReadOnly"; //$NON-NLS-1$
public static final String ERROR_NO_ACCESS = "FileNameValidator_Error_NoAccess"; //$NON-NLS-1$
public static final String ERROR_IS_RELATIV = "FileNameValidator_Error_IsRelativ"; //$NON-NLS-1$
public static final String ERROR_IS_ABSOLUT = "FileNameValidator_Error_IsAbsolut"; //$NON-NLS-1$
public static final String ERROR_NOT_RELATIV_TO_WS = "FileNameValidator_Error_NotRelativToWorkspace"; //$NON-NLS-1$
public static final String ERROR_HAS_SPACES = "FileNameValidator_Error_HasSpaces"; //$NON-NLS-1$
// arguments
private List<String> fileExtensions;
public static final int ATTR_MUST_EXIST = 2;
public static final int ATTR_CAN_READ = 4;
public static final int ATTR_CAN_WRITE = 8;
// if both attributes not set accept relative and absolute files
public static final int ATTR_ABSOLUT = 16;
public static final int ATTR_RELATIV = 32;
public static final int ATTR_NO_SPACES = 64;
public static final int ATTR_RELATIV_TO_WS = 128;
// next attribute should start with 2^8
// value attributes
private boolean isFile;
private boolean exists;
private boolean canRead;
private boolean canWrite;
private boolean absolute;
private boolean spaces;
/**
* Constructor
* @param attributes The validator attributes.
*/
public FileNameValidator(int attributes) {
super(attributes);
}
/**
* Constructor
* @param attributes The validator attributes.
*/
public FileNameValidator(int attributes, String[] fileExtensions) {
super(attributes);
setFileExtensions(fileExtensions);
}
/**
* Set the valid file extensions for attribute ATTR_FILE.
* @param fileExtensions The valid file extensions.
*/
public void setFileExtensions(String[] fileExtensions) {
this.fileExtensions = Arrays.asList(fileExtensions);
}
/**
* Return the valid file extensions for attribute ATTR_FILE.
* @return
*/
public String[] getFileExtensions() {
if (fileExtensions != null) {
return fileExtensions.toArray(new String[fileExtensions.size()]);
}
return new String[0];
}
/* (non-Javadoc)
* @see org.eclipse.tcf.te.ui.controls.validator.Validator#init()
*/
@Override
protected void init() {
super.init();
isFile = false;
exists = false;
canRead = false;
canWrite = false;
absolute = false;
spaces = false;
}
/* (non-Javadoc)
* @see org.eclipse.tcf.te.ui.controls.validator.Validator#isValid(java.lang.String)
*/
@Override
public boolean isValid(String newFile) {
init();
// info message when value is empty and mandatory
if (newFile == null || newFile.trim().length() == 0) {
if (isAttribute(ATTR_MANDATORY)) {
setMessage(getMessageText(INFO_MISSING_FILE_NAME), getMessageTextType(INFO_MISSING_FILE_NAME, INFORMATION));
return false;
}
return true;
}
newFile = newFile.trim();
File file = new File(newFile);
absolute = file.isAbsolute();
boolean relativToWs = false;
if (!absolute) {
IPath workSpacePath = ResourcesPlugin.getWorkspace().getRoot().getLocation();
File absFile = workSpacePath.append(new Path(file.toString())).toFile();
relativToWs = absFile.exists();
if (relativToWs) {
file = absFile;
}
}
exists = file.exists();
isFile = file.isFile() || !exists;
// To determine canRead and canWrite, we have to find the first existing parent directory
File parentFile = file.getParentFile();
while (parentFile != null && !parentFile.exists()) {
parentFile = parentFile.getParentFile();
}
canRead = file.canRead() || (!exists && parentFile != null && parentFile.canRead());
// *** Note: ***
// canWrite() may return false on some special folders on Windows like "My Documents".
// This is bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4939819.
canWrite = file.canWrite() || (!exists && parentFile != null && parentFile.canWrite());
spaces = file.toString().trim().indexOf(' ') > 0;
// Highest priority is MUST_EXIST
if (isAttribute(ATTR_MUST_EXIST) && !exists) {
setMessage(getMessageText(ERROR_MUST_EXIST), getMessageTextType(ERROR_MUST_EXIST, ERROR));
}
// Second test on spaces. If disallowed, the user should be told despite the other conditions
else if (isAttribute(ATTR_NO_SPACES) && spaces) {
setMessage(getMessageText(ERROR_HAS_SPACES), getMessageTextType(ERROR_HAS_SPACES, ERROR));
}
// Third: all the rest
else if (isAttribute(ATTR_ABSOLUT) && !isAttribute(ATTR_RELATIV) && !isAttribute(ATTR_RELATIV_TO_WS) && !absolute) {
setMessage(getMessageText(ERROR_IS_RELATIV), getMessageTextType(ERROR_IS_RELATIV, ERROR));
}
else if (isAttribute(ATTR_RELATIV) && !isAttribute(ATTR_ABSOLUT) && absolute) {
setMessage(getMessageText(ERROR_IS_ABSOLUT), getMessageTextType(ERROR_IS_ABSOLUT, ERROR));
}
else if (isAttribute(ATTR_RELATIV_TO_WS) && !absolute && !relativToWs) {
setMessage(getMessageText(ERROR_NOT_RELATIV_TO_WS), getMessageTextType(ERROR_NOT_RELATIV_TO_WS, ERROR));
}
else if (exists && !isFile) {
setMessage(getMessageText(ERROR_IS_DIRECTORY), getMessageTextType(ERROR_IS_DIRECTORY, ERROR));
}
else if (isFile && !hasValidExtension(newFile)) {
setMessage(getMessageText(ERROR_INVALID_FILE_NAME), getMessageTextType(ERROR_INVALID_FILE_NAME, ERROR));
}
else if (isAttribute(ATTR_CAN_READ) && !canRead) {
setMessage(getMessageText(ERROR_NO_ACCESS), getMessageTextType(ERROR_NO_ACCESS, ERROR));
}
else if (isAttribute(ATTR_CAN_WRITE) && !canWrite) {
setMessage(getMessageText(ERROR_READ_ONLY), getMessageTextType(ERROR_READ_ONLY, ERROR));
}
return getMessageType() != ERROR;
}
private boolean hasValidExtension(String newFile) {
if (fileExtensions != null && fileExtensions.size() > 0) {
Iterator<String> i = fileExtensions.iterator();
while (i.hasNext()) {
String ex = i.next().toLowerCase();
if (newFile.toLowerCase().endsWith(ex) ||
ex.equals("*") || ex.equals("*.*") || ex.equals(".*")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
return true;
}
}
return false;
}
return true;
}
/**
* Validated value is a file.
* @return
*/
public boolean isFile() {
return isFile;
}
/**
* Validated file exists.
* @return
*/
public boolean exists() {
return exists;
}
/**
* Validated file can be read.
* @return
*/
public boolean canRead() {
return canRead;
}
/**
* Validated file can be written.
* @return
*/
public boolean canWrite() {
return canWrite;
}
/**
* Validated file path is absolute.
* @return
*/
public boolean isAbsolute() {
return absolute;
}
/**
* Validated file path is relative.
* @return
*/
public boolean isRelative() {
return !absolute;
}
}