1 16 package org.apache.cocoon.xml; 17 18 import org.xml.sax.ContentHandler ; 19 import org.xml.sax.SAXException ; 20 21 58 public class NamespacesTable { 59 60 private Entry lastEntry; 61 62 65 private Entry lastDeclaredEntry; 66 67 private boolean usesScopes = false; 68 69 72 public NamespacesTable() { 73 clear(); 74 } 75 76 81 public void clear() { 82 this.lastEntry = Entry.create("",""); 83 this.addDeclaration("xml", "http://www.w3.org/XML/1998/namespace"); 84 this.lastEntry.closedScopes = 1; 86 } 87 88 93 public Declaration addDeclaration(String prefix, String uri) { 94 Entry dup = this.lastEntry; 96 while (dup != null && !dup.prefix.equals(prefix)) { 97 dup = dup.previous; 98 } 99 100 if (dup != null) { 101 if (usesScopes && dup.uri.equals(uri)) { 102 return dup; 103 } 104 dup.overriden = true; 105 } 106 107 Entry e = Entry.create(prefix, uri); 108 e.previous = this.lastEntry; 109 e.overrides = dup; 110 this.lastEntry = e; 111 this.lastDeclaredEntry = e; 113 return e; 114 } 115 116 125 public Declaration removeDeclaration(String prefix) { 126 if (usesScopes) { 127 return null; } 130 131 Entry current = this.lastEntry; 132 Entry afterCurrent = null; 133 while(current != null) { 134 if (current.closedScopes > 0) { 135 return null; 137 } 138 139 if (current.prefix.equals(prefix)) { 140 if (afterCurrent != null) { 143 afterCurrent.previous = current.previous; 144 } 145 current.previous.closedScopes += current.closedScopes; 147 Entry overrides = current.overrides; 148 if (overrides != null) { 149 overrides.overriden = false; 151 } 152 153 if (this.lastDeclaredEntry == current) { 154 if (current.previous.closedScopes == 0) { 155 this.lastDeclaredEntry = current.previous; 156 } else { 157 this.lastDeclaredEntry = null; 158 } 159 } 160 161 if (this.lastEntry == current) { 162 this.lastEntry = current.previous; 163 } 164 165 return current; 166 } 167 168 afterCurrent = current; 169 current = current.previous; 170 } 171 172 return null; 174 } 175 176 184 public void enterScope() { 185 this.usesScopes = true; 186 this.lastEntry.closedScopes++; 187 this.lastDeclaredEntry = null; 188 } 189 190 201 public void enterScope(ContentHandler handler) throws SAXException { 202 this.usesScopes = true; 203 Entry current = this.lastEntry; 204 while (current != null && current.closedScopes == 0) { 205 handler.startPrefixMapping(current.prefix, current.uri); 206 current = current.previous; 207 } 208 this.lastEntry.closedScopes++; 209 this.lastDeclaredEntry = null; 210 } 211 212 223 public void leaveScope() { 224 Entry current = this.lastEntry; 225 226 while (current.closedScopes == 0) { 228 current = current.previous; 229 } 230 231 current.closedScopes--; 232 233 if (current.closedScopes == 0) { 234 this.lastDeclaredEntry = current; 235 } else { 236 this.lastDeclaredEntry = null; 238 } 239 240 while (current != null && current.closedScopes == 0) { 241 Entry overrides = current.overrides; 242 if (overrides != null) { 243 overrides.overriden = false; 245 } 246 current = current.previous; 247 } 248 this.lastEntry = current; 249 } 250 251 264 public void leaveScope(ContentHandler handler) throws SAXException { 265 Entry current = this.lastEntry; 266 267 while (current.closedScopes == 0) { 269 current = current.previous; 270 } 271 272 current.closedScopes--; 273 274 if (current.closedScopes == 0) { 275 this.lastDeclaredEntry = current; 276 } else { 277 this.lastDeclaredEntry = null; 279 } 280 281 while (current != null && current.closedScopes == 0) { 282 handler.endPrefixMapping(current.prefix); 283 Entry overrides = current.overrides; 284 if (overrides != null) { 285 overrides.overriden = false; 287 } 288 current = current.previous; 289 } 290 291 this.lastEntry = current; 292 } 293 294 private static final Declaration[] NO_DECLS = new Declaration[0]; 295 296 302 public Declaration[] getCurrentScopeDeclarations() { 303 int count = 0; 304 Entry current = this.lastDeclaredEntry; 305 while (current != null && current.closedScopes == 0) { 306 count++; 307 current = current.previous; 308 } 309 310 if (count == 0) return NO_DECLS; 311 312 Declaration[] decls = new Declaration[count]; 313 count = 0; 314 current = this.lastDeclaredEntry; 315 while (current != null && current.closedScopes == 0) { 316 decls[count++] = current; 317 current = current.previous; 318 } 319 return decls; 320 } 321 322 326 public String getUri(String prefix) { 327 Entry current = this.lastEntry; 328 while (current != null) { 329 if (current.prefix.equals(prefix)) { 330 return current.uri; 331 } 332 current = current.previous; 333 } 334 335 return null; 337 } 338 339 347 public String [] getPrefixes(String uri) { 348 349 Entry current=this.lastEntry; 350 int count=0; 351 while (current!=null) { 352 if(!current.overriden && current.uri.equals(uri)) 353 count++; 354 current=current.previous; 355 } 356 if (count==0) return(new String [0]); 357 358 String prefixes[]=new String [count]; 359 count=0; 360 current = this.lastEntry; 361 while (current!=null) { 362 if(!current.overriden && current.uri.equals(uri)) 363 prefixes[count++] = current.prefix; 364 current = current.previous; 365 } 366 return prefixes; 367 } 368 369 370 374 public String getPrefix(String uri) { 375 Entry current = this.lastEntry; 376 while (current != null) { 377 if(!current.overriden && current.uri.equals(uri)) 378 return current.prefix; 379 current = current.previous; 380 } 381 return null; 382 } 383 384 395 public Name resolve(String uri, String raw, String prefix, String local) 396 throws SAXException { 397 if (uri==null) uri=""; 398 if (raw==null) raw=""; 399 if (prefix==null) prefix=""; 400 if (local==null) local=""; 401 if (raw.length()>0) { 403 int pos=raw.indexOf(':'); 405 if (pos>0) { 406 String pre=raw.substring(0,pos); 408 String loc=raw.substring(pos+1); 409 if (prefix.length()==0) prefix=pre; 410 else if (!prefix.equals(pre)) 411 throw new SAXException ("Raw/Prefix mismatch"); 412 if (local.length()==0) local=loc; 413 else if (!local.equals(loc)) 414 throw new SAXException ("Raw/Local Name mismatch"); 415 } else { 416 if (prefix.length()>0) 418 throw new SAXException ("Raw Name/Prefix mismatch"); 419 if (local.length()==0) local=raw; 420 else if (!local.equals(raw)) 421 throw new SAXException ("Raw Name/Local Name mismatch"); 422 } 423 } else { 424 if (local.length()==0) throw new SAXException ("No Raw/Local Name"); 426 if (prefix.length()==0) raw=local; 427 else raw=prefix+':'+local; 428 } 429 if (uri.length()>0) { 432 if ((prefix.length()>0) && (!uri.equals(this.getUri(prefix)))) { 434 throw new SAXException ("URI/Prefix mismatch [" + prefix + "," + uri + "]"); 435 } else { 436 String temp=this.getPrefix(uri); 437 if (temp==null) throw new SAXException ("URI not declared"); 438 else if (temp.length()>0) { 439 prefix=temp; 440 raw=prefix+':'+local; 441 } 442 } 443 } else { 444 String temp=this.getUri(prefix); 446 if (temp==null) throw new SAXException ("Prefix not declared"); 447 else uri=temp; 448 } 449 NameImpl name=new NameImpl(); 450 if (uri.length() > 0) name.uri=uri; 451 else name.uri=null; 452 name.raw=raw; 453 name.prefix=prefix; 454 name.local=local; 455 return(name); 456 } 457 458 459 private static class Entry implements Declaration { 460 461 protected String uri=""; 462 463 protected String prefix=""; 464 465 protected Entry previous; 466 protected Entry overrides; 467 protected int closedScopes = 0; 468 protected boolean overriden = false; 469 470 471 protected static Entry create(String prefix, String uri) { 472 Entry e = new Entry(); 474 if (prefix != null) e.prefix=prefix; 476 if (uri != null) e.uri=uri; 478 return e; 480 } 481 482 483 public String getUri() { return this.uri; } 484 485 public String getPrefix() { return this.prefix; } 486 } 487 488 489 private static class NameImpl implements Name { 490 491 protected String uri; 492 493 protected String prefix; 494 495 protected String local; 496 497 protected String raw; 498 499 500 public String getUri() { return this.uri; } 501 502 public String getPrefix() { return this.prefix; } 503 504 public String getLocalName() { return this.local; } 505 506 public String getQName() { return this.raw; } 507 } 508 509 513 public interface Name { 514 515 String getUri(); 516 517 String getPrefix(); 518 519 String getLocalName(); 520 521 String getQName(); 522 } 523 524 528 public interface Declaration { 529 530 String getUri(); 531 532 String getPrefix(); 533 } 534 } 535 | Popular Tags |