/* * Jajuk * Copyright (C) The Jajuk Team * http://jajuk.info * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ package org.jajuk.util; import java.io.File; import java.util.Locale; import javax.swing.filechooser.FileFilter; import org.apache.commons.lang.StringUtils; /** * Advanced file filter. * * * <p> * Example: new * JajukFilter(false,JajukFileFilter.DirectoryFilter.getInstance(), * JajukFileFilter.AudioFilter.getInstance()); * </p> * This class can be use by file choosers (probably a JajukFileChooser) and * for engine file selection that uses the raw accept method. In the second * case, it can be useful to use grouping filters like music or report (but * it is not intended to be used by file choosers that require only one * extension by filter) and or/and argument given as an argument */ public class JajukFileFilter extends FileFilter implements java.io.FileFilter, Const { // TODO: this class contains two things: filtering on a list of extensions, but also basic FileFiltering // that is overwritten later on, we should investigate if we can separate those two concerns... // also some filters do not really depend on JajukFileFilter, e.g. DirectoryFilter, and thus // might return incorrect data in certain cases, e.g. extension... /** Filters. */ private JajukFileFilter[] filters = {}; /** Show directories (useful to allow user to navigate). */ protected boolean bShowDirectories = false; /** List of Extensions for the current filter. */ protected String[] extensions = {}; protected String extensionsString = ""; /** And or OR applied to multi filters ?. */ private boolean bAND = true; /** * Filter constructor. * * @param bAND * @param filters undefined list of jajuk filter to be applied (logical AND applied * between filters) */ public JajukFileFilter(final boolean bAND, final JajukFileFilter... filters) { super(); this.bAND = bAND; this.filters = new JajukFileFilter[filters.length]; System.arraycopy(filters, 0, this.filters, 0, filters.length); } /** * Filter constructor. * * @param filters undefined list of jajuk filter to be applied (logical AND applied * between filters) * <p> * Example: only audio files new * JajukFilter(JajukFileFilter.AudioFilter.getInstance()); * </p> */ public JajukFileFilter(final JajukFileFilter... filters) { this(true, filters); } /** * Filter constructor, used mostly by subclasses to define type-safe * JajukFileFilters defining their own extensions lists, and occasionally * overriding some methods to influence the filtering process. * * @param extensions an array of extension strings */ public JajukFileFilter(final String[] extensions) { super(); this.extensions = (extensions != null) ? extensions : new String[] {}; final int size = this.extensions.length; for (int i = 0; i < size; i++) { this.extensions[i] = this.extensions[i].toLowerCase(Locale.getDefault()); extensionsString += this.extensions[i] + ','; } // Drop last coma if (!StringUtils.isBlank(extensionsString)) { extensionsString = extensionsString.substring(0, extensionsString.length() - 1); } } /** * Returns the filtering boolean status, after having combined all filters * with either an AND or OR logical rule. * * @param f file to test * * @return true, if accept */ @Override public boolean accept(final File f) { boolean acceptance = false; if (filters.length != 0) { boolean test = false; if (bAND) { test = true; for (final JajukFileFilter element : filters) { test &= element.accept(f); } } else { for (final JajukFileFilter element : filters) { test |= element.accept(f); } } acceptance = test; } else { acceptance = show(f); } return acceptance; } /* * (non-Javadoc) * * @see javax.swing.filechooser.FileFilter#getDescription() */ @Override public String getDescription() { return extensionsString; } /** * Returns an array of strings containing the extension patterns defined by * the current JajukFileFilter object instance. * * @return array of extension strings */ public String[] getExtensions() { // copy to not expose internal array String[] lExt = new String[extensions.length]; System.arraycopy(extensions, 0, lExt, 0, extensions.length); return lExt; } /** * Gets the filters. * * @return the filters */ public JajukFileFilter[] getFilters() { // copy to not expose internal array JajukFileFilter[] lFilter = new JajukFileFilter[filters.length]; System.arraycopy(filters, 0, lFilter, 0, filters.length); return lFilter; } /** * Checks if the given file's extension matches the ones expected by the * filter's registered extension. Beware that this method may be overwritten. * * @param file the file to be filtered * * @return known-extension flag */ protected boolean isKnownExtension(final File file) { if (file != null) { final String extension = UtilSystem.getExtension(file).toLowerCase(Locale.getDefault()); for (final String ext : extensions) { if (extension.equals(ext)) { return true; } } } return false; } /** * Force the filter to accept or reject directories. * * @param b directory acceptance flag */ public void setAcceptDirectories(final boolean b) { bShowDirectories = b; } /** * Checks if the given file should be shown, according if it is a directory * and that directory display is activated, or a file with a known extension. * Beware that this method or the isKnownExtension may be overwritten. * * @param file the file to be filtered * * @return display status flag (fallback is false) */ protected boolean show(final File file) { return (file.isDirectory()) ? bShowDirectories : (isKnownExtension(file)); } }