1 28 29 package org.jibx.runtime.impl; 30 31 import java.io.IOException ; 32 import java.util.Stack ; 33 34 import org.jibx.runtime.IXMLWriter; 35 36 43 44 public abstract class XMLWriterBase implements IXMLWriter 45 { 46 47 protected String [] m_uris; 48 49 50 protected boolean m_textSeen; 51 52 53 protected boolean m_contentSeen; 54 55 56 protected int m_nestingDepth; 57 58 59 protected String [] m_prefixes; 60 61 62 private Stack m_namespaceStack; 63 64 65 private int m_namespaceDepth; 66 67 68 private String [][] m_extensionUris; 69 70 71 private String [][] m_extensionPrefixes; 72 73 81 82 public XMLWriterBase(String [] uris) { 83 m_uris = uris; 84 m_prefixes = new String [uris.length]; 85 m_prefixes[0] = ""; 86 m_prefixes[1] = "xml"; 87 m_namespaceStack = new Stack (); 88 m_namespaceDepth = -1; 89 } 90 91 99 100 protected abstract void writeMarkup(String text) throws IOException ; 101 102 110 111 protected abstract void writeMarkup(char chr) throws IOException ; 112 113 120 121 protected abstract void defineNamespace(int index, String prefix) 122 throws IOException ; 123 124 129 130 protected abstract void undefineNamespace(int index); 131 132 139 140 protected abstract void writePrefix(int index) throws IOException ; 141 142 149 150 protected abstract void writeAttributeText(String text) throws IOException ; 151 152 163 164 public void writeXMLDecl(String version, String encoding, String standalone) 165 throws IOException { 166 writeMarkup("<?xml version=\""); 167 writeAttributeText(version); 168 if (encoding != null) { 169 writeMarkup("\" encoding=\""); 170 writeAttributeText(encoding); 171 } 172 if (standalone != null) { 173 writeMarkup("\" standalone=\""); 174 writeAttributeText(standalone); 175 } 176 writeMarkup("\"?>"); 177 } 178 179 187 188 public void startTagOpen(int index, String name) throws IOException { 189 indent(); 190 writeMarkup('<'); 191 writePrefix(index); 192 writeMarkup(name); 193 } 194 195 202 203 private void setNamespacePrefix(int index, String prefix) { 204 if (index < m_prefixes.length) { 205 m_prefixes[index] = prefix; 206 } else if (m_extensionUris != null) { 207 index -= m_prefixes.length; 208 for (int i = 0; i < m_extensionUris.length; i++) { 209 int length = m_extensionUris[i].length; 210 if (index < length) { 211 m_extensionPrefixes[i][index] = prefix; 212 break; 213 } else { 214 index -= length; 215 } 216 } 217 } 218 } 219 220 235 236 public void startTagNamespaces(int index, String name, 237 int[] nums, String [] prefs) throws IOException { 238 239 int count = 0; 241 for (int i = 0; i < nums.length; i++) { 242 if (!prefs[i].equals(getNamespacePrefix(nums[i]))) { 243 count++; 244 } 245 } 246 247 int[] deltas = null; 249 if (count > 0) { 250 251 String [] priors = new String [count]; 253 if (count == nums.length) { 254 255 deltas = nums; 257 for (int i = 0; i < count; i++) { 258 int slot = deltas[i]; 259 priors[i] = getNamespacePrefix(slot); 260 setNamespacePrefix(slot, prefs[i]); 261 defineNamespace(slot, prefs[i]); 262 } 263 264 } else { 265 266 int fill = 0; 268 deltas = new int[count]; 269 for (int i = 0; i < nums.length; i++) { 270 int slot = nums[i]; 271 String curr = getNamespacePrefix(slot); 272 if (!prefs[i].equals(curr)) { 273 deltas[fill] = slot; 274 priors[fill++] = curr; 275 setNamespacePrefix(slot, prefs[i]); 276 defineNamespace(slot, prefs[i]); 277 } 278 } 279 } 280 281 m_namespaceStack.push 283 (new DeclarationInfo(m_nestingDepth, deltas, priors)); 284 m_namespaceDepth = m_nestingDepth; 285 } 286 287 startTagOpen(index, name); 289 290 for (int i = 0; i < count; i++) { 292 int slot = deltas[i]; 293 String prefix = getNamespacePrefix(slot); 294 if (prefix.length() > 0) { 295 writeMarkup(" xmlns:"); 296 writeMarkup(prefix); 297 writeMarkup("=\""); 298 } else { 299 writeMarkup(" xmlns=\""); 300 } 301 writeAttributeText(getNamespaceUri(slot)); 302 writeMarkup('"'); 303 } 304 } 305 306 316 317 public void addAttribute(int index, String name, String value) 318 throws IOException { 319 writeMarkup(" "); 320 writePrefix(index); 321 writeMarkup(name); 322 writeMarkup("=\""); 323 writeAttributeText(value); 324 writeMarkup('"'); 325 } 326 327 332 333 public void closeNamespaces() { 334 335 DeclarationInfo info = (DeclarationInfo)m_namespaceStack.pop(); 337 int[] deltas = info.m_deltas; 338 String [] priors = info.m_priors; 339 for (int i = 0; i < deltas.length; i++) { 340 int index = deltas[i]; 341 undefineNamespace(index); 342 if (index < m_prefixes.length) { 343 m_prefixes[index] = null; 344 } else if (m_extensionUris != null) { 345 index -= m_prefixes.length; 346 for (int j = 0; j < m_extensionUris.length; j++) { 347 int length = m_extensionUris[j].length; 348 if (index < length) { 349 m_extensionPrefixes[j][index] = null; 350 } else { 351 index -= length; 352 } 353 } 354 } 355 } 356 357 if (m_namespaceStack.empty()) { 359 m_namespaceDepth = -1; 360 } else { 361 m_namespaceDepth = 362 ((DeclarationInfo)m_namespaceStack.peek()).m_depth; 363 } 364 } 365 366 372 373 public void closeStartTag() throws IOException { 374 writeMarkup('>'); 375 m_nestingDepth++; 376 m_textSeen = m_contentSeen = false; 377 } 378 379 385 386 public void closeEmptyTag() throws IOException { 387 writeMarkup("/>"); 388 if (m_nestingDepth == m_namespaceDepth) { 389 closeNamespaces(); 390 } 391 m_contentSeen = true; 392 } 393 394 402 403 public void startTagClosed(int index, String name) throws IOException { 404 indent(); 405 writeMarkup('<'); 406 writePrefix(index); 407 writeMarkup(name); 408 writeMarkup('>'); 409 m_nestingDepth++; 410 m_textSeen = m_contentSeen = false; 411 } 412 413 420 421 public void endTag(int index, String name) throws IOException { 422 --m_nestingDepth; 423 if (m_contentSeen && !m_textSeen) { 424 indent(); 425 } 426 writeMarkup("</"); 427 writePrefix(index); 428 writeMarkup(name); 429 writeMarkup('>'); 430 if (m_nestingDepth == m_namespaceDepth) { 431 closeNamespaces(); 432 } 433 m_textSeen = false; 434 m_contentSeen = true; 435 } 436 437 443 444 public void writeComment(String text) throws IOException { 445 writeMarkup("<!--"); 446 writeMarkup(text); 447 writeMarkup("-->"); 448 } 449 450 456 457 public void writeEntityRef(String name) throws IOException { 458 writeMarkup('&'); 459 writeMarkup(name); 460 writeMarkup(';'); 461 m_contentSeen = true; 462 } 463 464 474 475 public void writeDocType(String name, String sys, String pub, String subset) 476 throws IOException { 477 indent(); 478 writeMarkup("<!DOCTYPE "); 479 writeMarkup(name); 480 writeMarkup(' '); 481 if (sys != null) { 482 if (pub == null) { 483 writeMarkup("SYSTEM \""); 484 writeMarkup(sys); 485 } else { 486 writeMarkup("PUBLIC \""); 487 writeMarkup(pub); 488 writeMarkup("\" \""); 489 writeMarkup(sys); 490 } 491 writeMarkup('"'); 492 } 493 if (subset != null) { 494 writeMarkup('['); 495 writeMarkup(subset); 496 writeMarkup(']'); 497 } 498 writeMarkup('>'); 499 } 500 501 508 509 public void writePI(String target, String data) throws IOException { 510 indent(); 511 writeMarkup("<?"); 512 writeMarkup(target); 513 writeMarkup(' '); 514 writeMarkup(data); 515 writeMarkup("?>"); 516 m_contentSeen = true; 517 } 518 519 525 526 public abstract void close() throws IOException ; 527 528 533 534 public void reset() { 535 m_textSeen = m_contentSeen = false; 536 m_nestingDepth = 0; 537 m_namespaceDepth = -1; 538 m_namespaceStack.clear(); 539 m_extensionUris = null; 540 m_extensionPrefixes = null; 541 } 542 543 552 553 public String [] getNamespaces() { 554 return m_uris; 555 } 556 557 564 565 public String getNamespaceUri(int index) { 566 if (index < m_uris.length) { 567 return m_uris[index]; 568 } else if (m_extensionUris != null) { 569 index -= m_uris.length; 570 for (int i = 0; i < m_extensionUris.length; i++) { 571 int length = m_extensionUris[i].length; 572 if (index < length) { 573 return m_extensionUris[i][index]; 574 } else { 575 index -= length; 576 } 577 } 578 } 579 return null; 580 } 581 582 589 590 public String getNamespacePrefix(int index) { 591 if (index < m_prefixes.length) { 592 return m_prefixes[index]; 593 } else if (m_extensionUris != null) { 594 index -= m_prefixes.length; 595 for (int i = 0; i < m_extensionUris.length; i++) { 596 int length = m_extensionUris[i].length; 597 if (index < length) { 598 return m_extensionPrefixes[i][index]; 599 } else { 600 index -= length; 601 } 602 } 603 } 604 return null; 605 } 606 607 615 616 public int getPrefixIndex(String prefix) { 617 if (m_extensionPrefixes != null) { 618 for (int i = m_extensionPrefixes.length-1; i >= 0; i--) { 619 String [] prefixes = m_extensionPrefixes[i]; 620 for (int j = prefixes.length-1; j >= 0; j--) { 621 if (prefix.equals(prefixes[j])) { 622 int index = j + m_prefixes.length; 623 for (int k = i-1; k >= 0; k--) { 624 index += m_extensionPrefixes[k].length; 625 } 626 return index; 627 } 628 } 629 } 630 } 631 for (int i = m_prefixes.length-1; i >= 0; i--) { 632 if (prefix.equals(m_prefixes[i])) { 633 return i; 634 } 635 } 636 return -1; 637 } 638 639 647 648 protected static String [][] growArray(String [][] base, String [] items) { 649 if (base == null) { 650 return new String [][] { items }; 651 } else { 652 int length = base.length; 653 String [][] grow = new String [length+1][]; 654 System.arraycopy(base, 0, grow, 0, length); 655 grow[length] = items; 656 return grow; 657 } 658 } 659 660 667 668 protected static String [][] shrinkArray(String [][] base) { 669 int length = base.length; 670 if (length == 1) { 671 return null; 672 } else { 673 String [][] shrink = new String [length-1][]; 674 System.arraycopy(base, 0, shrink, 0, length-1); 675 return shrink; 676 } 677 } 678 679 684 685 public void pushExtensionNamespaces(String [] uris) { 686 m_extensionUris = growArray(m_extensionUris, uris); 687 m_extensionPrefixes = 688 growArray(m_extensionPrefixes, new String [uris.length]); 689 } 690 691 695 696 public void popExtensionNamespaces() { 697 m_extensionUris = shrinkArray(m_extensionUris); 698 m_extensionPrefixes = shrinkArray(m_extensionPrefixes); 699 } 700 701 709 710 public String [][] getExtensionNamespaces() { 711 return m_extensionUris; 712 } 713 714 718 719 private static class DeclarationInfo 720 { 721 722 public final int m_depth; 723 724 725 public final int[] m_deltas; 726 727 728 public final String [] m_priors; 729 730 731 public DeclarationInfo(int depth, int[] deltas, String [] priors) { 732 m_depth = depth; 733 m_deltas = deltas; 734 m_priors = priors; 735 } 736 } 737 } | Popular Tags |