0N/A/*
0N/A * CDDL HEADER START
0N/A *
0N/A * The contents of this file are subject to the terms of the
407N/A * Common Development and Distribution License (the "License").
0N/A * You may not use this file except in compliance with the License.
0N/A *
0N/A * See LICENSE.txt included in this distribution for the specific
0N/A * language governing permissions and limitations under the License.
0N/A *
0N/A * When distributing Covered Code, include this CDDL HEADER in each
0N/A * file and include the License file at LICENSE.txt.
0N/A * If applicable, add the following below this CDDL HEADER, with the
0N/A * fields enclosed by brackets "[]" replaced with your own identifying
0N/A * information: Portions Copyright [yyyy] [name of copyright owner]
0N/A *
0N/A * CDDL HEADER END
0N/A */
0N/A
0N/A/*
1416N/A * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
1416N/A *
1416N/A * Portions Apache software license, see below
1416N/A *
0N/A */
0N/Apackage org.opensolaris.opengrok.search.context;
0N/A
1416N/Apublic class WildCardMatcher extends LineMatcher {
0N/A
1002N/A final String pattern;
1190N/A
1138N/A public WildCardMatcher(String pattern, boolean caseInsensitive) {
1138N/A super(caseInsensitive);
1138N/A this.pattern = normalizeString(pattern);
0N/A }
1002N/A
1002N/A @Override
0N/A public int match(String token) {
1138N/A String tokenToMatch = normalizeString(token);
1416N/A return wildcardEquals(pattern, 0, tokenToMatch, 0)
1416N/A ? MATCHED
1416N/A : NOT_MATCHED;
1416N/A }
1416N/A //TODO below might be buggy, we might need to rewrite this anyways
1416N/A // so far keep it for the sake of 4.0 port
1416N/A /**
1416N/A * Licensed to the Apache Software Foundation (ASF) under one or more
1416N/A * contributor license agreements. See the NOTICE file distributed with this
1416N/A * work for additional information regarding copyright ownership. The ASF
1416N/A * licenses this file to You under the Apache License, Version 2.0 (the
1416N/A * "License"); you may not use this file except in compliance with the
1416N/A * License. You may obtain a copy of the License at
1416N/A *
1416N/A * http://www.apache.org/licenses/LICENSE-2.0
1416N/A *
1416N/A * Unless required by applicable law or agreed to in writing, software
1416N/A * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1416N/A * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1416N/A * License for the specific language governing permissions and limitations
1416N/A * under the License.
1416N/A */
1416N/A /**
1416N/A * ******************************************
1416N/A * String equality with support for wildcards
1416N/A * ******************************************
1416N/A */
1416N/A public static final char WILDCARD_STRING = '*';
1416N/A public static final char WILDCARD_CHAR = '?';
1416N/A
1416N/A /**
1416N/A * Determines if a word matches a wildcard pattern. <small>Work released by
1416N/A * Granta Design Ltd after originally being done on company time.</small>
1416N/A */
1416N/A public static boolean wildcardEquals(String pattern, int patternIdx,
1416N/A String string, int stringIdx) {
1416N/A int p = patternIdx;
1416N/A
1416N/A for (int s = stringIdx;; ++p, ++s) {
1416N/A // End of string yet?
1416N/A boolean sEnd = (s >= string.length());
1416N/A // End of pattern yet?
1416N/A boolean pEnd = (p >= pattern.length());
1416N/A
1416N/A // If we're looking at the end of the string...
1416N/A if (sEnd) {
1416N/A // Assume the only thing left on the pattern is/are wildcards
1416N/A boolean justWildcardsLeft = true;
1416N/A
1416N/A // Current wildcard position
1416N/A int wildcardSearchPos = p;
1416N/A // While we haven't found the end of the pattern,
1416N/A // and haven't encountered any non-wildcard characters
1416N/A while (wildcardSearchPos < pattern.length() && justWildcardsLeft) {
1416N/A // Check the character at the current position
1416N/A char wildchar = pattern.charAt(wildcardSearchPos);
1416N/A
1416N/A // If it's not a wildcard character, then there is more
1416N/A // pattern information after this/these wildcards.
1416N/A if (wildchar != WILDCARD_CHAR && wildchar != WILDCARD_STRING) {
1416N/A justWildcardsLeft = false;
1416N/A } else {
1416N/A // to prevent "cat" matches "ca??"
1416N/A if (wildchar == WILDCARD_CHAR) {
1416N/A return false;
1416N/A }
1416N/A
1416N/A // Look at the next character
1416N/A wildcardSearchPos++;
1416N/A }
1416N/A }
1416N/A
1416N/A // This was a prefix wildcard search, and we've matched, so
1416N/A // return true.
1416N/A if (justWildcardsLeft) {
1416N/A return true;
1416N/A }
1416N/A }
1416N/A
1416N/A // If we've gone past the end of the string, or the pattern,
1416N/A // return false.
1416N/A if (sEnd || pEnd) {
1416N/A break;
1416N/A }
1416N/A
1416N/A // Match a single character, so continue.
1416N/A if (pattern.charAt(p) == WILDCARD_CHAR) {
1416N/A continue;
1416N/A }
1416N/A
1416N/A //
1416N/A if (pattern.charAt(p) == WILDCARD_STRING) {
1416N/A // Look at the character beyond the '*' characters.
1416N/A while (p < pattern.length() && pattern.charAt(p) == WILDCARD_STRING) {
1416N/A ++p;
1416N/A }
1416N/A // Examine the string, starting at the last character.
1416N/A for (int i = string.length(); i >= s; --i) {
1416N/A if (wildcardEquals(pattern, p, string, i)) {
1416N/A return true;
1416N/A }
1416N/A }
1416N/A break;
1416N/A }
1416N/A if (pattern.charAt(p) != string.charAt(s)) {
1416N/A break;
1416N/A }
1416N/A }
1416N/A return false;
0N/A }
0N/A}