001/* 002 A clean reimplementation of Ptolemy II's original ExtensionFilenameFilter. 003 004 Copyright (c) 2016 The Regents of the University of California. 005 All rights reserved. 006 Permission is hereby granted, without written agreement and without 007 license or royalty fees, to use, copy, modify, and distribute this 008 software and its documentation for any purpose, provided that the above 009 copyright notice and the following two paragraphs appear in all copies 010 of this software. 011 012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016 SUCH DAMAGE. 017 018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 ENHANCEMENTS, OR MODIFICATIONS. 024 025 PT_COPYRIGHT_VERSION_2 026 COPYRIGHTENDKEY 027*/ 028package ptolemy.gui; 029 030import java.io.File; 031import java.util.HashSet; 032import java.util.List; 033import java.util.Locale; 034import java.util.Set; 035 036/** 037 * An implementation of both javax.swing.filechooser.FileFilter and 038 * java.io.FilenameFilter that only accepts files that have one of the 039 * registered extensions. 040 * <p> 041 * This class is provided in Ptolemy II to support usage with both 042 * java.awt.FileDialog and javax.swing.JFileChooser. As it appears that on 043 * MacOSX the FileDialog implementation is better than the JFileChooser, Ptolemy 044 * II has some logic in ptolemy.gui.PtGUIUtilities.useFileDialog() to decide 045 * which "file-picker"-component to use. Several Ptolemy II classes use this 046 * utility while still passing a common filter instance to the selected 047 * component. (e.g. ptolemy.gui.Query, ptolemy.gui.Top ...) 048 * </p> 049 * <p> 050 * The javax.swing.filechooser.FileNameExtensionFilter in the JDK can only be 051 * used with JFileChooser. 052 * </p> 053 * 054 * @version $Id$ 055 * @author Erwin De Ley 056 * @since Ptolemy II 11.0 057 */ 058public class ExtensionFilenameFilter extends PtFilenameFilter { 059 060 /** 061 * Construct a file filter that filters out all files that do not 062 * have one of the extensions in the given list. 063 * 064 * @param extensions the file extensions to use 065 */ 066 public ExtensionFilenameFilter(List<String> extensions) { 067 for (String ext : extensions) { 068 registerExtension(ext); 069 } 070 } 071 072 /** 073 * Construct a file filter that filters out all files that do not 074 * have one of the extensions in the given list. 075 * 076 * @param extensions the file extensions to use 077 */ 078 public ExtensionFilenameFilter(String[] extensions) { 079 // This method is used by Kepler in gui/src/org/kepler/gui/kar/OpenArchiveAction.java 080 // See https://kepler-project.org/developers. To build: "ant change-to -Dsuite=nightly; ant compile" 081 this(extensions, null); 082 } 083 084 /** 085 * Creates a filter that accepts the given file type, specified by 086 * a number of extensions and a meaningful description of the file 087 * types involved. 088 * 089 * @param description a description of the types of files with one 090 * of the given extensions. 091 * @param extensions the file extensions to use 092 */ 093 public ExtensionFilenameFilter(String description, String... extensions) { 094 for (String ext : extensions) { 095 registerExtension(ext); 096 } 097 setDescription(description); 098 } 099 100 /** 101 * Creates a filter that accepts the given file type, specified by 102 * a number of extensions and a meaningful description of the file 103 * types involved. 104 * 105 * @param extensions the file extensions to use 106 * @param description a description of the types of files with one 107 * of the given extensions 108 */ 109 public ExtensionFilenameFilter(String[] extensions, String description) { 110 // This method is used by Kepler in reporting/src/org/kepler/reporting/gui/ReportDesignerPanel.java 111 // See https://kepler-project.org/developers. To build: "ant change-to -Dsuite=nightly; ant compile" 112 for (int i = 0; i < extensions.length; i++) { 113 registerExtension(extensions[i]); 114 } 115 if (description != null) { 116 setDescription(description); 117 } 118 } 119 120 /** 121 * Return true if the given file has one of the registered 122 * extensions, or is a directory. Otherwise, or if the file is 123 * null, return false. 124 * 125 * <p>Files whose name begins with "." are not accepted.</p> 126 * 127 * @param file The file to be checked. 128 * @return true if the given file has one of the registered 129 * extensions, or is a directory. 130 */ 131 @Override 132 public boolean accept(File file) { 133 if (file == null) { 134 return false; 135 } else if (file.isDirectory()) { 136 return true; 137 } else { 138 String ext = _getExtension(file); 139 return (ext != null && _registeredExtensions.contains(ext)); 140 } 141 } 142 143 /** 144 * Return true if the given file name has one of the registered 145 * extensions, or is a directory. Otherwise, or if the directory 146 * or name is null, return false. 147 * 148 * <p>Files whose name begins with "." are not accepted.</p> 149 * 150 * @param directory the parent directory of the file 151 * @param name the name of the file. 152 * @return true if the given file has one of the registered 153 * extensions, or is a directory. 154 */ 155 @Override 156 public boolean accept(File directory, String name) { 157 if (name == null || directory == null) { 158 return false; 159 } else { 160 return accept(new File(directory, name)); 161 } 162 } 163 164 /** 165 * @return The human readable description of the types of files 166 * accepted by this filter. 167 * @see #setDescription(String) 168 */ 169 @Override 170 public String getDescription() { 171 return _description; 172 } 173 174 /** 175 * Set the human readable description of the types of files accepted by this 176 * filter. 177 * 178 * @param description the human readable description of the types 179 * of files accepted by this filter. 180 * @see #getDescription() 181 */ 182 public void setDescription(String description) { 183 _description = description; 184 } 185 186 /** Get the description and the registered extensions. 187 * @return description + registered extensions 188 */ 189 @Override 190 public String toString() { 191 return getDescription() + " : " + _registeredExtensions; 192 } 193 194 /////////////////////////////////////////////////////////////////// 195 //// protected methods //// 196 /** 197 * Register an additional extension to accept. 198 * 199 * @param extension 200 * The extension to be added. 201 */ 202 protected void registerExtension(String extension) { 203 if (extension == null || "".equals(extension.trim())) { 204 return; 205 } else { 206 _registeredExtensions 207 .add(extension.trim().toLowerCase(Locale.getDefault())); 208 } 209 } 210 211 /////////////////////////////////////////////////////////////////// 212 //// private methods //// 213 /** 214 * Return the extension of the given file. 215 * <p> 216 * If the file is null, if it's name does not contain a '.', or if it ends 217 * in a '.', this method returns null. 218 * </p> 219 * 220 * @param file The file 221 * @return the extension of the file or null if the file is null, 222 * or if it has no extension. 223 */ 224 private String _getExtension(File file) { 225 if (file == null) { 226 return null; 227 } else { 228 String fileName = file.getName(); 229 int i = fileName.lastIndexOf('.'); 230 if (i > 0 && i < fileName.length() - 1) { 231 String ext = fileName.substring(i + 1); 232 return ext.toLowerCase(Locale.getDefault()); 233 } else { 234 return null; 235 } 236 } 237 } 238 239 /////////////////////////////////////////////////////////////////// 240 //// private fields //// 241 private Set<String> _registeredExtensions = new HashSet<String>(); 242 243 private String _description = null; 244}