2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright (c) 1999 by Sun Microsystems, Inc.
2N/A * All rights reserved.
2N/A *
2N/A */
2N/A
2N/A// AttributePattern.java: Models a pattern for attribute matching.
2N/A// Author: James Kempf
2N/A// Created On: Tue Feb 3 15:26:30 1998
2N/A// Last Modified By: James Kempf
2N/A// Last Modified On: Thu Aug 6 14:33:57 1998
2N/A// Update Count: 19
2N/A//
2N/A
2N/Apackage com.sun.slp;
2N/A
2N/Aimport java.util.*;
2N/Aimport java.io.*;
2N/A
2N/A/**
2N/A * The AttributePattern class models an attribute pattern. It handles
2N/A * wildcard matching of lowercased, space-compressed strings. Each
2N/A * element in the parts vector is a PatternPart object. A PatternPart
2N/A * object is a pattern consisting of (maximally) a beginning wildcard and
2N/A * string pattern. A PatternPart may be lacking the
2N/A * any of these, but will always have at least one.
2N/A *
2N/A * @author James Kempf
2N/A */
2N/A
2N/Aclass AttributePattern extends AttributeString {
2N/A
2N/A private static final String WILDCARD = "*";
2N/A
2N/A private Vector parts = new Vector();
2N/A
2N/A /**
2N/A * The PatternPart class models a single component of a pattern.
2N/A * It may have a beginning wildcard and string
2N/A * pattern in the middle. Any of the parts may be missing, but it will
2N/A * always have at least one.
2N/A *
2N/A * @author James Kempf
2N/A */
2N/A
2N/A
2N/A private class PatternPart extends Object {
2N/A
2N/A boolean wildcard = false;
2N/A String pattern = "";
2N/A
2N/A PatternPart(boolean wc, String str) {
2N/A wildcard = wc;
2N/A pattern = str;
2N/A
2N/A }
2N/A }
2N/A
2N/A AttributePattern(String str, Locale locale) {
2N/A
2N/A super(str, locale);
2N/A
2N/A // Parse out wildcards into PatternPart objects.
2N/A
2N/A // If there's no wildcards, simply insert the string in as the pattern.
2N/A
2N/A if (cstring.indexOf(WILDCARD) == -1) {
2N/A parts.addElement(new PatternPart(false, cstring));
2N/A
2N/A } else {
2N/A
2N/A // Parse the patterns into parts.
2N/A
2N/A StringTokenizer tk = new StringTokenizer(cstring, WILDCARD, true);
2N/A
2N/A while (tk.hasMoreTokens()) {
2N/A String middle = "";
2N/A boolean wc = false;
2N/A
2N/A String tok = tk.nextToken();
2N/A
2N/A // Beginning wildcard, or, if none, then the middle.
2N/A
2N/A if (tok.equals(WILDCARD)) {
2N/A wc = true;
2N/A
2N/A // Need to look for middle.
2N/A
2N/A if (tk.hasMoreTokens()) {
2N/A middle = tk.nextToken();
2N/A
2N/A }
2N/A
2N/A } else {
2N/A middle = tok;
2N/A
2N/A }
2N/A
2N/A // Note that there may be a terminal pattern part that just
2N/A // consists of a wildcard.
2N/A
2N/A parts.addElement(new PatternPart(wc, middle));
2N/A }
2N/A }
2N/A }
2N/A
2N/A boolean isWildcarded() {
2N/A return (parts.size() > 1);
2N/A
2N/A }
2N/A
2N/A // Match the AttributeString object against this pattern,
2N/A // returning true if they match.
2N/A
2N/A public boolean match(AttributeString str) {
2N/A String cstring = str.cstring;
2N/A int offset = 0, len = cstring.length();
2N/A int i = 0, n = parts.size();
2N/A boolean match = true;
2N/A
2N/A // March through the parts, matching against the string.
2N/A
2N/A for (; i < n; i++) {
2N/A PatternPart p = (PatternPart)parts.elementAt(i);
2N/A
2N/A // If there's a wildcard, check the remainder of the string for
2N/A // the pattern.
2N/A
2N/A if (p.wildcard) {
2N/A
2N/A // Note that if the pattern string is empty (""), then this
2N/A // will return offset, but on the next iteration, it will
2N/A // fall out of the loop because an empty pattern string
2N/A // can only occur at the end (like "foo*").
2N/A
2N/A if ((offset = cstring.indexOf(p.pattern, offset)) == -1) {
2N/A
2N/A // The pattern was not found. Break out of the loop.
2N/A
2N/A match = false;
2N/A break;
2N/A }
2N/A
2N/A offset += p.pattern.length();
2N/A
2N/A // We are at the end of the string.
2N/A
2N/A if (offset >= len) {
2N/A
2N/A // If we are not at the end of the pattern, then we may not
2N/A // have a match.
2N/A
2N/A if (i < (n - 1)) {
2N/A
2N/A // If there is one more in the pattern, and it is
2N/A // a pure wildcard, then we *do* have a match.
2N/A
2N/A if (i == (n - 2)) {
2N/A p = (PatternPart)parts.elementAt(i+1);
2N/A
2N/A if (p.wildcard == true &&
2N/A p.pattern.length() <= 0) {
2N/A break;
2N/A
2N/A }
2N/A }
2N/A
2N/A match = false;
2N/A
2N/A }
2N/A
2N/A // Break out of the loop, no more string to analyze.
2N/A
2N/A break;
2N/A }
2N/A
2N/A } else {
2N/A
2N/A // The pattern string must match the beginning part of the
2N/A // argument string.
2N/A
2N/A if (!cstring.regionMatches(offset,
2N/A p.pattern,
2N/A 0,
2N/A p.
2N/A pattern.length())) {
2N/A match = false;
2N/A break;
2N/A
2N/A }
2N/A
2N/A // Bump up offset by the pattern length, and exit if
2N/A // we're beyond the end of the string.
2N/A
2N/A offset += p.pattern.length();
2N/A
2N/A if (offset >= len) {
2N/A break;
2N/A
2N/A }
2N/A }
2N/A }
2N/A
2N/A return match;
2N/A }
2N/A}