1 19 20 package org.netbeans.editor; 21 22 import java.util.HashMap ; 23 import java.util.ArrayList ; 24 25 40 41 public final class TokenContextPath { 42 43 44 private static final HashMap registry = new HashMap (199); 45 46 47 private TokenContext[] contexts; 48 49 50 private TokenContextPath parent; 51 52 53 private TokenContextPath base; 54 55 58 private String namePrefix; 59 60 61 private final HashMap tokenNameCache = new HashMap (); 62 63 64 private final HashMap replaceStartCache = new HashMap (); 65 66 67 static synchronized TokenContextPath get(TokenContext[] contexts) { 68 if (contexts == null || contexts.length == 0) { 69 throw new IllegalArgumentException ("Contexts must be valid and non-empty."); } 71 72 ArrayMatcher am = new ArrayMatcher(contexts); 73 TokenContextPath path = (TokenContextPath)registry.get(am); 74 if (path == null) { 75 path = new TokenContextPath(contexts); 76 registry.put(am, path); 77 } 78 79 return path; 80 } 81 82 83 private TokenContextPath(TokenContext[] contexts) { 84 this.contexts = contexts; 85 86 if (contexts.length == 1) { 87 base = this; } 89 } 90 91 94 public TokenContext[] getContexts() { 95 return contexts; 96 } 97 98 99 public int length() { 100 return contexts.length; 101 } 102 103 106 public TokenContextPath getParent() { 107 if (parent == null && contexts.length > 1) { 108 TokenContext[] parentContexts = new TokenContext[contexts.length - 1]; 109 System.arraycopy(contexts, 0, parentContexts, 0, contexts.length - 1); 110 111 parent = get(parentContexts); 112 } 113 114 return parent; 115 } 116 117 121 public TokenContextPath getBase() { 122 if (base == null) { 123 base = getParent().getBase(); 124 } 125 126 return base; 127 } 128 129 133 public boolean contains(TokenContextPath tcp) { 134 if (tcp == this) { 135 return true; 136 137 } else if (contexts.length > 1) { 138 return getParent().contains(tcp); 139 140 } else { 141 return false; 142 } 143 } 144 145 156 public TokenContextPath replaceStart(TokenContextPath byPath) { 157 if (contexts.length < byPath.contexts.length) { 159 throw new IllegalArgumentException ("byPath=" + byPath + " is too long."); } 161 162 synchronized (replaceStartCache) { 163 TokenContextPath ret = (TokenContextPath)replaceStartCache.get(byPath); 164 if (ret == null) { 165 TokenContext[] targetContexts = (TokenContext[])contexts.clone(); 166 for (int i = byPath.contexts.length - 1; i >= 0; i--) { 167 targetContexts[i] = byPath.contexts[i]; 168 } 169 ret = get(targetContexts); 170 replaceStartCache.put(byPath, ret); 171 } 172 173 return ret; 174 } 175 } 176 177 178 public String getNamePrefix() { 179 if (namePrefix == null) { 180 if (contexts.length == 1) { 181 namePrefix = contexts[0].getNamePrefix(); 182 183 } else { namePrefix = (contexts[contexts.length - 1].getNamePrefix() 185 + getParent().getNamePrefix()).intern(); 186 } 187 } 188 189 return namePrefix; 190 } 191 192 196 public String getFullTokenName(TokenCategory tokenIDOrCategory) { 197 String tokenName = tokenIDOrCategory.getName(); 198 String fullName; 199 synchronized (tokenNameCache) { 200 fullName = (String )tokenNameCache.get(tokenName); 201 if (fullName == null) { 202 fullName = (getNamePrefix() + tokenName).intern(); 203 tokenNameCache.put(tokenName, fullName); 204 } 205 } 206 207 return fullName; 208 } 209 210 public String toString() { 211 StringBuffer sb = new StringBuffer ("|"); for (int i = 0; i < contexts.length; i++) { 213 String shortName = contexts[i].getClass().getName(); 214 shortName = shortName.substring(shortName.lastIndexOf('.') + 1); 215 216 sb.append('<'); 217 sb.append(shortName); 218 sb.append('>'); 219 } 220 sb.append('|'); 221 222 return sb.toString(); 223 } 224 225 private static final class ArrayMatcher { 226 227 228 private int hash; 229 230 private TokenContext[] contexts; 231 232 ArrayMatcher(TokenContext[] contexts) { 233 this.contexts = contexts; 234 } 235 236 public int hashCode() { 237 int h = hash; 238 if (h == 0) { 239 for (int i = contexts.length - 1; i >= 0; i--) { 240 h = h * 31 + contexts[i].hashCode(); } 242 hash = h; 243 } 244 245 return h; 246 } 247 248 public boolean equals(Object o) { 249 if (this == o) { 250 return true; 251 } 252 253 if (o instanceof ArrayMatcher) { 254 ArrayMatcher am = (ArrayMatcher)o; 255 if (contexts.length == am.contexts.length) { 256 for (int i = contexts.length - 1; i >= 0; i--) { 257 if (!contexts[i].equals(am.contexts[i])) { 258 return false; 259 } 260 } 261 return true; 262 } 263 } 264 265 return false; 266 } 267 268 } 269 270 } 271 | Popular Tags |