/* * Copyright 2004 - 2009 Christian Sprajc. All rights reserved. * * This file is part of PowerFolder. * * PowerFolder 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. * * PowerFolder 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 PowerFolder. If not, see <http://www.gnu.org/licenses/>. * * $Id: CompilingPatternMatch.java 8022 2009-05-21 07:46:07Z harry $ */ package de.dal33t.powerfolder.util.pattern; /** * Compiling pattern matcher that uses compiled parts to match '*' characters to * any text. So 'a*c' would match 'ac', 'abc', 'asdfkhc', etc. */ public class CompiledPattern extends AbstractPattern { /** Precompiled parts to match on. */ private String[] partsLower; private String[] partsUpper; /** True if pattern begins with '*'. */ private boolean firstStar; /** True if pattern ends with '*'. */ private boolean lastStar; /** * Constructor. * * @param patternStringArg */ public CompiledPattern(String patternStringArg) { super(patternStringArg); // Everything is case-insensitive. String patternString = patternStringArg.toLowerCase().trim(); // If it starts with a '*', we can scan forward to find an initial // match. if (patternString.startsWith("*")) { patternString = patternString.substring(1); firstStar = true; } // If it ends with a '*', there can be tail characters in the match // string. if (patternString.endsWith("*")) { patternString = patternString.substring(0, patternString.length() - 1); lastStar = true; } // Precompile pattern into parts. partsLower = patternString.split("\\*"); partsUpper = new String[partsLower.length]; for (int i = 0; i < partsLower.length; i++) { String partLower = partsLower[i]; partsUpper[i] = partLower.toUpperCase(); } } public boolean isMatch(String matchString) { int index = 0; for (int i = 0; i < partsLower.length; i++) { index = indexOf(matchString, i, index); boolean first = i == 0; boolean last = i + 1 == partsLower.length; if (index == -1) { return false; } if (first && !firstStar && index != 0) { return false; } String part = partsLower[i]; if (last && !lastStar && index + part.length() != matchString.length()) { return false; } } return index != -1; } private int indexOf(String source, int partNo, int fromIndex) { String partLower = partsLower[partNo]; String partUpper = partsUpper[partNo]; if (fromIndex >= source.length()) { return (partLower.length() == 0 ? source.length() : -1); } if (fromIndex < 0) { fromIndex = 0; } if (partLower.length() == 0) { return fromIndex; } char firstLower = partLower.charAt(0); char firstUpper = partUpper.charAt(0); int max = source.length() - partLower.length(); for (int i = fromIndex; i <= max; i++) { /* Look for first character. */ if (!equalChar(source.charAt(i), firstLower, firstUpper)) { while (++i <= max && !equalChar(source.charAt(i), firstLower, firstUpper)); } /* Found first character, now look at the rest of v2 */ if (i <= max) { int j = i + 1; int end = j + partLower.length() - 1; for (int k = 1; j < end && equalChar(source.charAt(j), partLower.charAt(k), partUpper.charAt(k)); j++, k++); if (j == end) { /* Found whole string. */ return i; } } } return -1; } }