Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.topologi.diffx.format;
  
  /* ============================================================================
   * ARTISTIC LICENCE
   * 
   * Preamble
   * 
   * The intent of this document is to state the conditions under which a Package
   * may be copied, such that the Copyright Holder maintains some semblance of 
  * artistic control over the development of the package, while giving the users
  * of the package the right to use and distribute the Package in a more-or-less
  * customary fashion, plus the right to make reasonable modifications.
  *
  * Definitions:
  *  - "Package" refers to the collection of files distributed by the Copyright 
  *    Holder, and derivatives of that collection of files created through 
  *    textual modification.
  *  - "Standard Version" refers to such a Package if it has not been modified, 
  *    or has been modified in accordance with the wishes of the Copyright 
  *    Holder.
  *  - "Copyright Holder" is whoever is named in the copyright or copyrights 
  *    for the package.
  *  - "You" is you, if you're thinking about copying or distributing this 
  *    Package.
  *  - "Reasonable copying fee" is whatever you can justify on the basis of 
  *    media cost, duplication charges, time of people involved, and so on. 
  *    (You will not be required to justify it to the Copyright Holder, but only 
  *    to the computing community at large as a market that must bear the fee.)
  *  - "Freely Available" means that no fee is charged for the item itself, 
  *    though there may be fees involved in handling the item. It also means 
  *    that recipients of the item may redistribute it under the same conditions
  *    they received it.
  *
  * 1. You may make and give away verbatim copies of the source form of the 
  *    Standard Version of this Package without restriction, provided that you 
  *    duplicate all of the original copyright notices and associated 
  *    disclaimers.
  *
  * 2. You may apply bug fixes, portability fixes and other modifications 
  *    derived from the Public Domain or from the Copyright Holder. A Package 
  *    modified in such a way shall still be considered the Standard Version.
  *
  * 3. You may otherwise modify your copy of this Package in any way, provided 
  *    that you insert a prominent notice in each changed file stating how and 
  *    when you changed that file, and provided that you do at least ONE of the 
  *    following:
  * 
  *    a) place your modifications in the Public Domain or otherwise make them 
  *       Freely Available, such as by posting said modifications to Usenet or 
  *       an equivalent medium, or placing the modifications on a major archive 
  *       site such as ftp.uu.net, or by allowing the Copyright Holder to 
  *       include your modifications in the Standard Version of the Package.
  * 
  *    b) use the modified Package only within your corporation or organization.
  *
  *    c) rename any non-standard executables so the names do not conflict with 
  *       standard executables, which must also be provided, and provide a 
  *       separate manual page for each non-standard executable that clearly 
  *       documents how it differs from the Standard Version.
  * 
  *    d) make other distribution arrangements with the Copyright Holder.
  *
  * 4. You may distribute the programs of this Package in object code or 
  *    executable form, provided that you do at least ONE of the following:
  * 
  *    a) distribute a Standard Version of the executables and library files, 
  *       together with instructions (in the manual page or equivalent) on where
  *       to get the Standard Version.
  *
  *    b) accompany the distribution with the machine-readable source of the 
  *       Package with your modifications.
  * 
  *    c) accompany any non-standard executables with their corresponding 
  *       Standard Version executables, giving the non-standard executables 
  *       non-standard names, and clearly documenting the differences in manual 
  *       pages (or equivalent), together with instructions on where to get 
  *       the Standard Version.
  *
  *    d) make other distribution arrangements with the Copyright Holder.
  *
  * 5. You may charge a reasonable copying fee for any distribution of this 
  *    Package. You may charge any fee you choose for support of this Package. 
  *    You may not charge a fee for this Package itself. However, you may 
  *    distribute this Package in aggregate with other (possibly commercial) 
  *    programs as part of a larger (possibly commercial) software distribution 
  *    provided that you do not advertise this Package as a product of your own.
  *
  * 6. The scripts and library files supplied as input to or produced as output 
  *    from the programs of this Package do not automatically fall under the 
  *    copyright of this Package, but belong to whomever generated them, and may
  *    be sold commercially, and may be aggregated with this Package.
  *
  * 7. C or perl subroutines supplied by you and linked into this Package shall 
  *    not be considered part of this Package.
  *
  * 8. The name of the Copyright Holder may not be used to endorse or promote 
  *    products derived from this software without specific prior written 
  *    permission.
  * 
 * 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED 
 *    WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 
 *    MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 * ============================================================================
 */
A simple XML formatter that writes strictly what it is given.

This formatter will write the events exactly in the order in which they are given, in other words, there is no way to prevent this class from writing malformed XML. On other hand, the SmartXMLFormatter will close XML elements automatically, therefore rectifying a lot of the errors that lead to malformed XML.

Author(s):
Christophe Lauret
Version:
3 April 2005
public final class StrictXMLFormatter implements XMLDiffXFormatter {
// class attributes ---------------------------------------------------------------------------

  
Thw output goes here.
  private final PrintWriter xml;

  
The open 'del' tag, that is the element start tag that we put before test is being deleted.
  private String openDel = "<del>";

  
The close 'del' tag, that is the element end tag that we put after test is being deleted.
  private String closeDel = "</del>";

  
The open 'ins' tag, that is the element start tag that we put before test is being inserted.
  private String openIns = "<ins>";

  
The close 'ins' tag, that is the element end tag that we put after test is being inserted.
  private String closeIns = "</ins>";

  
The DiffX configuration to use
  private DiffXConfig config = new DiffXConfig(); 
// state variables ----------------------------------------------------------------------------

  
Set to false once the prefix mapping has been declared.
   xmlns:dfx="http://www.allette.com.au/diffex"
 
  private transient boolean declareNamespace = true

  
Set to true to indicate that there is an open 'ins' tag.
  private transient boolean isInserting = false;

  
Set to true to indicate that there is an open 'del' tag.
  private transient boolean isDeleting = false;

  
Set to true to indicate that there is an open element tag that does not have its right angle bracket.
  private transient boolean isElementNude = false;

  
Set to true to include the XML declaration. This attribute is set to false when the setWriteXMLDeclaration(boolean) is called with false or once the XML declaration has been written.
  private transient boolean writeXMLDeclaration = true;
// constructors -------------------------------------------------------------------------------

  
Creates a new formatter on the standard output.
  public StrictXMLFormatter() {
    this. = new PrintWriter(.);
    init();
  }

  
Creates a new formatter using the specified writer.

Parameters:
w The writer to use.
  public StrictXMLFormatter(Writer w) {
    this. = new PrintWriter(w);
    init();
  }
// methods ------------------------------------------------------------------------------------

  
Writes the XML declaration.
  private void init() {
    .println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
  }

  
  public void format(DiffXEvent ethrows IOException {
    // an element to open
    if (e instanceof OpenElementEvent) {
      if (this.denudeElement();
      // close any ins / del tag 
      if (closeIns();
      if (closeDel();
      OpenElementEvent oee = (OpenElementEvent)e;
      this..print('<'+oee.getName());
      if (this.) {
        this..print(" xmlns:dfx=\""+.+"\"");
        this. = false;
      }
      this. = true;
    // an element to close
    } else if (e instanceof CloseElementEvent) {
      if (this.denudeElement();
      // close any ins / del tag 
      if (closeIns();
      if (closeDel();
      this..print(e.toXML());
    // an attribute
    } else if (e instanceof AttributeEvent) {
      if (this.) {
        this..print(e.toXML());
      } else {
        throw new IllegalStateException("Cannot write an attribute once the element is closed");
      }
    // this is text
    } else {
      // close any ins / del tag
      if (this.denudeElement();
      if (closeIns();
      if (closeDel();
      // a character sequence
      if (e instanceof WordEvent || e instanceof SpaceEvent) {
        this..print(e.toXML());
      // a single character
      } else if (e instanceof CharEvent) {
        this..print(((CharEvent)e).);
      }
    }
    this..flush();
  }

  
  public void insert(DiffXEvent ethrows IOException {
    // insert element
    if (e instanceof OpenElementEvent) {
      if (this.denudeElement();
      if (closeDel();
      OpenElementEvent oee = (OpenElementEvent)e;
      this..print('<'+oee.getName());
      if (this.)
        this..print(" xmlns:dfx=\"http://www.allette.com.au/diffex\"");
      this..print(" dfx:insert=\"true\"");
      this. = true;
    // an element to close
    } else if (e instanceof CloseElementEvent) {
      if (this.denudeElement();
      if (closeDel();
      this..print("</");
      this..print(((CloseElementEvent)e).getName());
      this..print('>');
    } else if (e instanceof AttributeEvent) {
        if (this.) {
          this..print(" ");
          this..print(((AttributeEvent)e).getName());
          this..print("=\"");
          this..print(((AttributeEvent)e).getValue());
          this..print('"');
        } else {
          throw new IllegalStateException("Cannot insert an attribute once the element is closed");
        }
    // now we handle text tokens
    } else {
      
      // close any del tag
      if (this.denudeElement();
      if (closeDel();
      // a word
      if (e instanceof WordEvent) {
        if (!this.openIns();
        this..print(e.toXML());
      // a white space
      } else if (e instanceof SpaceEvent) {
        this..print(e.toXML());
      // wrap the char in a <ins> element
      } else if (e instanceof CharEvent) {
        this..print(((CharEvent)e).);
      }
    }
    this..flush();
  }

  
  public void delete(DiffXEvent ethrows IOExceptionIllegalStateException {
    // we ignore delete attributes
    if (this.denudeElement();
    if (closeIns();
    // delete an element
    if (e instanceof OpenElementEvent) {
      OpenElementEvent oee = (OpenElementEvent)e;
      this..print('<'+oee.getName());
      if (this.)
        this..print(" xmlns:dfx=\"http://www.allette.com.au/diffex\"");
      this..print(" dfx:delete=\"true\"");
      this..print('>');
    // an element to close
    } else if (e instanceof CloseElementEvent) {
      this..print("</");
      this..print(((CloseElementEvent)e).getName());
      this..print('>');
    // text
    } else {
      // a word
      if (e instanceof WordEvent) {
        if (!this.openDel();
        this..print(e.toXML());
      // a white space
      } else if (e instanceof SpaceEvent) {
        this..print(e.toXML());
      // wrap the char in a <ins> element
      } else if (e instanceof CharEvent) {
        this..print(((CharEvent)e).);
      }
    }
    this..flush();
  }

  
Sets the open and end tags for inserted text.

The default values are "<ins:>" and "</ins:>" respectively.

Parameters:
start The open tag for inserts.
end The close tag for inserts.
Throws:
java.lang.NullPointerException If any of the tags is null.
  public void setInsertTags(String startString endthrows NullPointerException {
    if (start == null
      throw new NullPointerException("The start element for inserted text must have a value");
    if (end == null
      throw new NullPointerException("The start element for inserted text must have a value");
    this. = start;
    this. = end;
  }

  
Sets the open and end tags for deleted text.

The default values are "<del:>" and "</del:>" respectively.

Parameters:
start The open tag for deletions.
end The close tag for deletions.
Throws:
java.lang.NullPointerException If any of the tags is null.
  public void setDeleteTags(String startString endthrows NullPointerException {
    if (start == null
      throw new NullPointerException("The start element for deleted text must have a value");
    if (end == null
      throw new NullPointerException("The start element for deleted text must have a value");
    this. = start;
    this. = end;
  }

  

See also:
com.topologi.diffx.format.DiffXFormatter#setConfig(com.topologi.diffx.DiffXConfig )
  public void setConfig(DiffXConfig config) {
    this. = config;
  }

  
  public void setWriteXMLDeclaration(boolean show) {
    this. = show;
  }
// private helpers ----------------------------------------------------------------------------

  
Opens the 'ins' element, and update the state flags.
  private void openIns() {
    this..print(this.);
    this. = true;
  }

  
Opens the 'del' element, and update the state flags.
  private void openDel() {
    this..print(this.);
    this. = true;
  }

  
Closes the 'ins' element, and update the state flags.
  private void closeIns() {
    this..print(this.);
    this. = false;
  }

  
Closes the 'del' element, and update the state flags.
  private void closeDel() {
    this..print(this.);
    this. = false;
  }

  
Closes the 'del' element, and update the state flags.
  private void denudeElement() {
    this..print(">");
    this. = false;
  }
New to GrepCode? Check out our FAQ X