Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * This file is part of the DiffX library.
   *
   * For licensing information please see the file license.txt included in the release.
   * A copy of this licence can also be found at
   *   http://www.opensource.org/licenses/artistic-license-2.0.php
   */
  package com.topologi.diffx.xml;
  
 import java.io.Writer;
 import java.util.List;
 import java.util.Map;
 
A Namespace-aware writer for XML data.

Provides methods to generate well-formed XML data easily. wrapping a writer.

This version only supports utf-8 encoding, if writing to a file make sure that the encoding of the file output stream is "utf-8".

The recommended implementation is to use a BufferedWriter to write.

  Writer writer =
     new BufferedWriter(new OutputStreamWriter(new FileOutputStream("foo.out"),"utf-8"));
 

This class is not synchronised.

Author(s):
Christophe Lauret - Allette Systems (Australia)
Version:
11 December 2011
 
 public final class XMLWriterNSImpl extends XMLWriterBase implements XMLWriter {

  
Set to true to show debug info.
 
   private static final boolean DEBUG = false;

  
The default namespace mapped to the empty prefix.
 
The root node.
 
   private static final Element ROOT;
   static {
     List<PrefixMappingmps = new ArrayList<PrefixMapping>();
     mps.add();
      = new Element(""truemps);
   }

  
The current prefix mapping.
 
   private final Map<StringStringprefixMapping = new HashMap<StringString>();

  
The list of prefix mappings to be associated with the next element.
 
   private List<PrefixMappingtempMapping;

  
A stack of elements to close the elements automatically.
 
   private final List<Elementelements = new ArrayList<Element>();
 
   // Constructors
   // ----------------------------------------------------------------------------------------------
 
  

Creates a new XML writer.

Sets the depth attribute to 0 and the indentation to true.

Parameters:
writer Where this writer should write the XML data.
Throws:
java.lang.NullPointerException If the writer is null.
 
   public XMLWriterNSImpl(Writer writerthrows NullPointerException {
     this(writerfalse);
   }

  

Create a new XML writer.

Parameters:
writer Where this writer should write the XML data.
indent Set the indentation flag.
Throws:
java.lang.NullPointerException If the writer is null.
  public XMLWriterNSImpl(Writer writerboolean indentthrows NullPointerException {
    super(writerindent);
    this..add();
  }

  
Writes the angle bracket if the element open tag is not finished.

Throws:
java.io.IOException If thrown by the wrapped writer.
  void deNude() throws IOException {
    if (this.) {
      this..write('>');
      if (super. && peekElement().) {
        this..write('\n');
      }
      this. = false;
    }
  }
  // Open/close specific elements
  // ----------------------------------------------------------------------------------------------

  
Writes a start element tag correctly indented.

It is the same as openElement(null, name, false)

Parameters:
name the name of the element
Throws:
java.io.IOException If thrown by the wrapped writer.
See also:
openElement(java.lang.String,java.lang.String,boolean)
  public void openElement(String namethrows IOException {
    openElement(nullnamefalse);
  }

  
Write a start element tag correctly indented.

It is the same as openElement(name, false)

Parameters:
uri The namespace URI of this element.
name The name of the element.
Throws:
java.io.IOException If thrown by the wrapped writer.
See also:
openElement(java.lang.String,boolean)
  public void openElement(String uriString namethrows IOException {
    openElement(urinamefalse);
  }

  
Writes a start element tag correctly indented.

Use the hasChildren parameter to specify whether this element is terminal node or not, note: this affects the indenting. To produce correctly indented XML, you should use the same value for this flag when closing the element.

The name can contain attributes and should be a valid xml name.

Parameters:
name The name of the element.
hasChildren true if this element has children.
Throws:
java.io.IOException If thrown by the wrapped writer.
  public void openElement(String nameboolean hasChildrenthrows IOException {
    openElement(nullnamehasChildren);
  }

  
Writes a start element tag correctly indented.

Use the hasChildren parameter to specify whether this element is terminal node or not, note: this affects the indenting. To produce correctly indented XML, you should use the same value for this flag when closing the element.

The name can contain attributes and should be a valid xml name.

Parameters:
uri The namespace URI of this element.
name The name of the element.
hasChildren true if this element has children.
Throws:
java.io.IOException If thrown by the wrapped writer.
  public void openElement(String uriString nameboolean hasChildrenthrows IOException {
    deNude();
    indent();
    String qName = getQName(uriname);
    this..add(new Element(qNamehasChildrenthis.));
    this..write('<');
    this..write(qName);
    this. = true;
    this.++;
  }

  
Write an end element tag.

Throws:
java.io.IOException If thrown by the wrapped writer.
  public void closeElement() throws IOException {
    Element elt = popElement();
    // reaching the end of the document
    if (elt == )
      throw new IllegalCloseElementException();
    this.--;
    // this is an empty element
    if (this.) {
      this..write('/');
      this. = false;
      // the element contains text
    } else {
      if (elt.hasChildren) {
        indent();
      }
      this..write('<');
      this..write('/');
      int x = elt.qName.indexOf(' ');
      if (x < 0) {
        this..write(elt.qName);
      } else {
        this..write(elt.qName.substring(0, x));
      }
    }
    // restore previous mapping if necessary
    this..write('>');
    // take care of the new line if the indentation is on
    if (super.) {
      Element parent = peekElement();
      if (parent.hasChildren && parent != ) {
        this..write('\n');
      }
    }
  }

  
Same as emptyElement(null, element);.

Parameters:
element the name of the element
Throws:
java.io.IOException If thrown by the wrapped writer.
  public void emptyElement(String elementthrows IOException {
    emptyElement(nullelement);
  }

  
Write an empty element.

It is possible for the element to contain attributes, however, since there is no character escaping, great care must be taken not to introduce invalid characters. For example:

    <example test="yes"/>
 

Parameters:
uri The namespace URI for this element.
element The name of the element.
Throws:
java.io.IOException If thrown by the wrapped writer.
  public void emptyElement(String uriString elementthrows IOException {
    deNude();
    indent();
    this..write('<');
    this..write(getQName(urielement));
    this..write('/');
    this..write('>');
    if (super.) {
      this..write('\n');
    }
  }

  
Returns the last element in the list.

Returns:
The current element.
  private Element peekElement() {
    return this..get(this..size() - 1);
  }

  
Removes the last element in the list.

Returns:
The current element.
  private Element popElement() {
    return this..remove(this..size() - 1);
  }

  
Writes an attribute.

Parameters:
uri The namespcae URI this attribute belongs to.
name The name of the attribute.
value The value of the attribute.
Throws:
java.io.IOException If thrown by the wrapped writer.
java.lang.IllegalStateException If there is no open element or text has been written.
  public void attribute(String uriString nameString value)
      throws IOExceptionIllegalStateException {
    if (!this.throw new IllegalArgumentException("Cannot write attribute: too late!");
    this..write(' ');
    this..write(getQName(uriname));
    this..write("=\"");
    this..writeAttValue(value);
    this..write('"');
  }

  
Writes an attribute.

This method for number does not require escaping.

Parameters:
uri The namespcae URI this attribute belongs to.
name The name of the attribute.
value The value of the attribute.
Throws:
java.io.IOException If thrown by the wrapped writer.
java.lang.IllegalStateException If there is no open element or text has been written.
  public void attribute(String uriString nameint value)
      throws IOExceptionIllegalStateException {
    if (!this.throw new IllegalArgumentException("Cannot write attribute: too late!");
    this..write(' ');
    this..write(getQName(uriname));
    this..write("=\"");
    this..write(Integer.toString(value));
    this..write('"');
  }
  // Namespace handling
  // ----------------------------------------------------------------------------------------------

  

Parameters:
uri The full namespace URI.
prefix The prefix for the namespace uri.
Throws:
java.lang.NullPointerException if the prefix is null.
See also:
XMLWriter.setPrefixMapping(java.lang.String,java.lang.String)

This implementation does not keep a history of the prefix mappings so it needs to be reset. If a prefix is already being used it is overridden.

  public void setPrefixMapping(String uriString prefixthrows NullPointerException {
    //do not declare again if the same mapping already exist
    if (!prefix.equals(this..get(uri))) {
      // remove the previous mapping to the prefix
      removeIfNeeded(prefix);
      // create the new prefix mapping
      PrefixMapping pm = new PrefixMapping(prefixuri);
      this..put(pm.uripm.prefix);
      if () {
        ..println(pm.prefix+" -> "+pm.uri);
      }
      if (this. == null) {
        this. = new ArrayList<PrefixMapping>();
      }
      this..add(pm);
    }
  }

  
Returns the qualified name for this element using the specified namespace URI.

Parameters:
uri The namespace URI for the element.
name The name of the element or attribute.
Returns:
The qualified element name.
Throws:
UndeclaredNamespaceException If the uri has not being previously declared.
  private String getQName(String uriString namethrows UndeclaredNamespaceException {
    String prefix = this..get(uri != nulluri : "");
    if (prefix != null) {
      if (!"".equals(prefix))
        return this..get(uri)+":"+name;
      else
        return name;
    } else if (uri == nullreturn name;
    else
      throw new UndeclaredNamespaceException(uri);
  }

  
Handles the namespace declaration and updates the prefix mappings.

Throws:
java.io.IOException If thrown by the wrapped writer.
  private void handleNamespaceDeclaration() throws IOException {
    if (this. != null) {
      PrefixMapping pm = null;
      for (int i = 0; i < this..size(); i++) {
        pm = this..get(i);
        if (!..equals(pm.prefix)) {
          this..write(" xmlns");
          // specify a prefix if different from ""
          if (!"".equals(pm.prefix)) {
            this..write(':');
            this..write(pm.prefix);
          }
          this..write("=\"");
          this..write(pm.uri);
          this..write("\"");
        }
      }
      this. = null;
    }
  }

  
Restores the prefix mapping after closing an element.

This costly operation need only to be done if the method setPrefixMapping(java.lang.String,java.lang.String) have been used immediately before, therefore it should not happen often.

Parameters:
elt The element that had some new mappings.
  private void restorePrefixMapping(Element elt) {
    if (elt.mappings != null) {
      // for each mapping of this element
      for (int i = 0; i < elt.mappings.size(); i++) {
        PrefixMapping mpi = elt.mappings.get(i);
        if () {
          ..print(mpi.prefix+" -< ");
        }
        // find the first previous namespace mapping amongst the parents
        // that defines namespace mappings
        for (int j = this..size() - 1; j > 0; j--) {
          if (this..get(j). != null) {
            List<PrefixMappingmps = this..get(j).;
            // iterate through the define namespace mappings of the parent
            for (int k = 0; k < mps.size(); k++) {
              PrefixMapping mpk = mps.get(k);
              // if we found a namespace prefix for the namespace
              if (mpk.prefix.equals(mpi.prefix)) {
                removeIfNeeded(mpk.prefix);
                this..put(mpk.urimpk.prefix);
                if () {
                  ..println(mpk.uri+" [R]");
                }
                j = 0; // exit from the previous loop
                break// exit from this one
              }
            }
          }
        }
      }
    }
  }

  
Removes the mapping associated to the specified prefix.

Parameters:
prefix The prefix which mapping should be removed.
  private void removeIfNeeded(String prefix) {
    // remove the previous mapping to the prefix
    if (this..containsValue(prefix)) {
      Entry<StringStringremove = null;
      for (Entry<StringStringe : this..entrySet()) {
        if (e.getValue().equals(prefix)) {
          remove = e;
          break;
        }
      }
      // we know key should have a value
      this..remove(remove.getKey());
    }
  }

  
Close the writer.

Throws:
java.io.IOException If thrown by the wrapped writer.
UnclosedElementException If an element has been left open.
  public void close() throws IOExceptionUnclosedElementException {
    Element open = peekElement();
    if (open != .)
      throw new UnclosedElementException(open.qName);
    this..close();
  }
  // Inner class: Element
  // ----------------------------------------------------------------------------------------------

  
A light object to keep track of the elements

Author(s):
Christophe Lauret (Allette Systems)
Version:
31 August 2004
  private static final class Element {

    
The fully qualified name of the element.
    private final String qName;

    
Indicates whether the element has children.
    private final boolean hasChildren;

    
A list of prefix mappings for this element.

Can be null.

    private final List<PrefixMappingmappings;

    
Creates a new Element.

Parameters:
qName The qualified name of the element.
hasChildren Whether the element has children.
mappings The list of prefix mapping if any.
    public Element(String qNameboolean hasChildrenList<PrefixMappingmappings) {
      this. = qName;
      this. = hasChildren;
      this. = mappings;
    }
  }
  // Inner class: Prefix Mapping
  // ----------------------------------------------------------------------------------------------

  
Light-weight class to represent a prefix mapping.

The class attributes cannot be null.

Author(s):
Christophe Lauret (Allette Systems)
Version:
31 August 2004
  private static final class PrefixMapping {

    
The prefix associated to the URI.
    private final String prefix;

    
The namespace URI.
    private final String uri;

    
Creates a new prefix mapping.

Parameters:
prefix The prefix for the URI.
uri The full namespace URI.
    public PrefixMapping(String prefixString uri) {
      this. = prefix != nullprefix : "";
      this. = uri != nulluri : "";
    }
  }
New to GrepCode? Check out our FAQ X