1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1999 by Sun Microsystems, Inc. 23 * All rights reserved. 24 * 25 */ 26 27 // AttributePattern.java: Models a pattern for attribute matching. 28 // Author: James Kempf 29 // Created On: Tue Feb 3 15:26:30 1998 30 // Last Modified By: James Kempf 31 // Last Modified On: Thu Aug 6 14:33:57 1998 32 // Update Count: 19 33 // 34 35 package com.sun.slp; 36 37 import java.util.*; 38 import java.io.*; 39 40 /** 41 * The AttributePattern class models an attribute pattern. It handles 42 * wildcard matching of lowercased, space-compressed strings. Each 43 * element in the parts vector is a PatternPart object. A PatternPart 44 * object is a pattern consisting of (maximally) a beginning wildcard and 45 * string pattern. A PatternPart may be lacking the 46 * any of these, but will always have at least one. 47 * 48 * @author James Kempf 49 */ 50 51 class AttributePattern extends AttributeString { 52 53 private static final String WILDCARD = "*"; 54 55 private Vector parts = new Vector(); 56 57 /** 58 * The PatternPart class models a single component of a pattern. 59 * It may have a beginning wildcard and string 60 * pattern in the middle. Any of the parts may be missing, but it will 61 * always have at least one. 62 * 63 * @author James Kempf 64 */ 65 66 67 private class PatternPart extends Object { 68 69 boolean wildcard = false; 70 String pattern = ""; 71 72 PatternPart(boolean wc, String str) { 73 wildcard = wc; 74 pattern = str; 75 76 } 77 } 78 79 AttributePattern(String str, Locale locale) { 80 81 super(str, locale); 82 83 // Parse out wildcards into PatternPart objects. 84 85 // If there's no wildcards, simply insert the string in as the pattern. 86 87 if (cstring.indexOf(WILDCARD) == -1) { 88 parts.addElement(new PatternPart(false, cstring)); 89 90 } else { 91 92 // Parse the patterns into parts. 93 94 StringTokenizer tk = new StringTokenizer(cstring, WILDCARD, true); 95 96 while (tk.hasMoreTokens()) { 97 String middle = ""; 98 boolean wc = false; 99 100 String tok = tk.nextToken(); 101 102 // Beginning wildcard, or, if none, then the middle. 103 104 if (tok.equals(WILDCARD)) { 105 wc = true; 106 107 // Need to look for middle. 108 109 if (tk.hasMoreTokens()) { 110 middle = tk.nextToken(); 111 112 } 113 114 } else { 115 middle = tok; 116 117 } 118 119 // Note that there may be a terminal pattern part that just 120 // consists of a wildcard. 121 122 parts.addElement(new PatternPart(wc, middle)); 123 } 124 } 125 } 126 127 boolean isWildcarded() { 128 return (parts.size() > 1); 129 130 } 131 132 // Match the AttributeString object against this pattern, 133 // returning true if they match. 134 135 public boolean match(AttributeString str) { 136 String cstring = str.cstring; 137 int offset = 0, len = cstring.length(); 138 int i = 0, n = parts.size(); 139 boolean match = true; 140 141 // March through the parts, matching against the string. 142 143 for (; i < n; i++) { 144 PatternPart p = (PatternPart)parts.elementAt(i); 145 146 // If there's a wildcard, check the remainder of the string for 147 // the pattern. 148 149 if (p.wildcard) { 150 151 // Note that if the pattern string is empty (""), then this 152 // will return offset, but on the next iteration, it will 153 // fall out of the loop because an empty pattern string 154 // can only occur at the end (like "foo*"). 155 156 if ((offset = cstring.indexOf(p.pattern, offset)) == -1) { 157 158 // The pattern was not found. Break out of the loop. 159 160 match = false; 161 break; 162 } 163 164 offset += p.pattern.length(); 165 166 // We are at the end of the string. 167 168 if (offset >= len) { 169 170 // If we are not at the end of the pattern, then we may not 171 // have a match. 172 173 if (i < (n - 1)) { 174 175 // If there is one more in the pattern, and it is 176 // a pure wildcard, then we *do* have a match. 177 178 if (i == (n - 2)) { 179 p = (PatternPart)parts.elementAt(i+1); 180 181 if (p.wildcard == true && 182 p.pattern.length() <= 0) { 183 break; 184 185 } 186 } 187 188 match = false; 189 190 } 191 192 // Break out of the loop, no more string to analyze. 193 194 break; 195 } 196 197 } else { 198 199 // The pattern string must match the beginning part of the 200 // argument string. 201 202 if (!cstring.regionMatches(offset, 203 p.pattern, 204 0, 205 p. 206 pattern.length())) { 207 match = false; 208 break; 209 210 } 211 212 // Bump up offset by the pattern length, and exit if 213 // we're beyond the end of the string. 214 215 offset += p.pattern.length(); 216 217 if (offset >= len) { 218 break; 219 220 } 221 } 222 } 223 224 return match; 225 } 226 } 227