001/* 002 * Syncany, www.syncany.org 003 * Copyright (C) 2011-2016 Philipp C. Heckel <philipp.heckel@gmail.com> 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package org.syncany.config; 019 020import java.io.File; 021import java.io.FileNotFoundException; 022import java.util.HashSet; 023import java.util.Scanner; 024import java.util.Set; 025import java.util.logging.Level; 026import java.util.logging.Logger; 027 028/** 029 * This class serves as a container of patterns of filenames 030 * that should be ignored. 031 * 032 * @author Pim Otte 033 */ 034public class IgnoredFiles { 035 private static final Logger logger = Logger.getLogger(ConfigHelper.class.getSimpleName()); 036 037 private Set<String> ignorePatterns; 038 private Set<String> ignorePaths; 039 private File ignoreFile; 040 041 public IgnoredFiles(File ignoreFile) { 042 this.ignoreFile = ignoreFile; 043 this.ignorePatterns = new HashSet<String>(); 044 this.ignorePaths = new HashSet<String>(); 045 046 loadPatterns(); 047 } 048 049 /** 050 * Method to check whether a file should be ignored. 051 * Should only be called at indexing time. 052 */ 053 public boolean isFileIgnored(String filePath, String fileName) { 054 // Check all exact paths 055 for (String path : ignorePaths) { 056 if (path.equals(filePath)) { 057 return true; 058 } 059 } 060 061 // Check all recursive 062 for (String path : ignorePaths) { 063 if (path.equals(fileName)) { 064 return true; 065 } 066 } 067 068 // Check all regular expressions 069 for (String pattern : ignorePatterns) { 070 if (filePath.matches(pattern)) { 071 return true; 072 } 073 } 074 075 return false; 076 } 077 078 public void loadPatterns() { 079 if (ignoreFile != null && ignoreFile.exists()) { 080 try { 081 Scanner scanner = new Scanner(ignoreFile); 082 083 while (scanner.hasNextLine()) { 084 String ignorePatternLine = scanner.nextLine().trim(); 085 086 if (!ignorePatternLine.isEmpty()) { 087 parseIgnoreFileLine(ignorePatternLine); 088 } 089 } 090 091 scanner.close(); 092 } 093 catch (FileNotFoundException e) { 094 logger.log(Level.INFO, "Ignore file not found (existed before).", e); 095 } 096 } 097 else { 098 // In case the ignoreFile has been deleted, reset patterns 099 ignorePatterns = new HashSet<String>(); 100 ignorePaths = new HashSet<String>(); 101 } 102 } 103 104 private void parseIgnoreFileLine(String ignorePattern) { 105 if (ignorePattern.startsWith("regex:")) { 106 // Chop off regex: indicator 107 ignorePatterns.add(ignorePattern.substring(6)); 108 } 109 else { 110 if (ignorePattern.contains("*") || ignorePattern.contains("?")) { 111 // wildcards handling, converting them to regexps 112 ignorePatterns.add(convertWildcardsToRegexp(ignorePattern)); 113 } 114 else { 115 ignorePaths.add(ignorePattern); 116 } 117 } 118 } 119 120 private static String convertWildcardsToRegexp(String in) { 121 StringBuilder out = new StringBuilder("^"); 122 123 for (int i = 0; i < in.length(); ++i) { 124 char c = in.charAt(i); 125 126 switch (c) { 127 case '*': 128 out.append(".*"); 129 break; 130 case '?': 131 out.append('.'); 132 break; 133 case '.': 134 case '$': 135 case '^': 136 case '{': 137 case '}': 138 case '[': 139 case ']': 140 case '(': 141 case ')': 142 case '|': 143 case '+': 144 case '\\': 145 out.append('\\'); 146 out.append(c); 147 break; 148 default: 149 out.append(c); 150 } 151 } 152 153 out.append('$'); 154 155 return out.toString(); 156 } 157}