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