/*******************************************************************************
* Copyright (c) 2008 xored software, Inc.
*
* 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:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.tcl.core;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
import org.eclipse.dltk.compiler.CharOperation;
public class TclCheckContentExclude implements IPropertyChangeListener {
private char[][] cachedPatterns = null;
public boolean isExcluded(String name) {
char[][] patterns;
synchronized (this) {
if (cachedPatterns == null) {
final Preferences prefs = TclPlugin.getDefault()
.getPluginPreferences();
initPatterns(prefs
.getString(TclCorePreferences.CHECK_CONTENT_EXCLUDES));
prefs.addPropertyChangeListener(this);
}
patterns = cachedPatterns;
}
if (patterns.length != 0) {
for (int i = 0; i < patterns.length; ++i) {
final char[] pattern = patterns[i];
if (match(pattern, name)) {
return true;
}
}
}
return false;
}
/**
* @param string
*/
private void initPatterns(String value) {
cachedPatterns = CharOperation.splitOn(
TclCorePreferences.CHECK_CONTENT_EXCLUDE_SEPARATOR, value
.toCharArray());
if (cachedPatterns == null) {
cachedPatterns = CharOperation.NO_CHAR_CHAR;
}
}
private static final boolean match(char[] pattern, String name) {
final int patternEnd = pattern.length;
final int nameEnd = name.length();
int iPattern = 0; // patternStart;
int iName = 0; // nameStart
/* check first segment */
char patternChar = 0;
while ((iPattern < patternEnd)
&& (patternChar = pattern[iPattern]) != '*') {
if (iName == nameEnd)
return false;
if (patternChar != Character.toLowerCase(name.charAt(iName))
&& patternChar != '?') {
return false;
}
iName++;
iPattern++;
}
/* check sequence of star+segment */
int segmentStart;
if (patternChar == '*') {
segmentStart = ++iPattern; // skip star
} else {
segmentStart = 0; // force iName check
}
int prefixStart = iName;
checkSegment: while (iName < nameEnd) {
if (iPattern == patternEnd) {
iPattern = segmentStart; // mismatch - restart current
// segment
iName = ++prefixStart;
continue checkSegment;
}
/* segment is ending */
if ((patternChar = pattern[iPattern]) == '*') {
segmentStart = ++iPattern; // skip start
if (segmentStart == patternEnd) {
return true;
}
prefixStart = iName;
continue checkSegment;
}
/* check current name character */
if (Character.toLowerCase(name.charAt(iName)) != patternChar
&& patternChar != '?') {
iPattern = segmentStart; // mismatch - restart current
// segment
iName = ++prefixStart;
continue checkSegment;
}
iName++;
iPattern++;
}
return (segmentStart == patternEnd)
|| (iName == nameEnd && iPattern == patternEnd)
|| (iPattern == patternEnd - 1 && pattern[iPattern] == '*');
}
public void propertyChange(PropertyChangeEvent event) {
if (TclCorePreferences.CHECK_CONTENT_EXCLUDES.equals(event
.getProperty())) {
synchronized (this) {
initPatterns((String) event.getNewValue());
}
}
}
}