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.load;
  
 import java.io.File;
 import java.util.List;
 
 
Records the SAX events in an com.topologi.diffx.sequence.EventSequence.

It is possible to specify the name of the XML reader implementation class. By default this class will try to use the Crimson parser org.apache.crimson.parser.XMLReaderImpl.

The XML reader implementation must support the following features settings

   http://xml.org/sax/features/validation         => false
   http://xml.org/sax/features/namespaces         => true | false
   http://xml.org/sax/features/namespace-prefixes => true | false
 

Author(s):
Christophe Lauret
Jean-Baptiste Reure
Version:
17 October 2006
 
 public final class SAXRecorder implements XMLRecorder {
 
   // static variables -------------------------------------------------------------------------------
 
  
The XML reader.
 
   private static XMLReader reader;

  
The default XML reader in use.
 
   private static final String DEFAULT_XML_READER;
   static {
     String className;
     try {
       className = XMLReaderFactory.createXMLReader().getClass().getName();
     } catch (SAXException ex) {
       // FIXME: Exception handling!!!
       //      className = XMLReaderImpl.class.getName();
       className = "";
     }
      = className;
   }

  
The XML reader class in use (set to the deafult XML reader).
 
   private static String readerClassName = ;

  
Indicates whether a new reader instance should be created because the specified class name has changed.
 
   private static boolean newReader = true;
 
   // class attributes -------------------------------------------------------------------------------
 
  
The DiffX configuration to use
 
  private DiffXConfig config = new DiffXConfig();

  
The sequence of event for this recorder.
  protected transient EventSequence sequence;
  // methods implementing XMLRecorder -------------------------------------------------------

  
Runs the recorder on the specified file.

This method will count on the org.xml.sax.InputSource to guess the correct encoding.

Parameters:
file The file to process.
Returns:
The recorded sequence of events.
Throws:
LoadingException If thrown while parsing.
java.io.IOException Should I/O error occur.
  public EventSequence process(File filethrows LoadingExceptionIOException {
    InputStream in = new BufferedInputStream(new FileInputStream(file));
    EventSequence seq = null;
    seq = process(new InputSource(in));
    in.close();
    in = null;
    return seq;
  }

  
Runs the recorder on the specified string.

This method is provided for convenience. It is best to only use this method for short strings.

Parameters:
xml The XML string to process.
Returns:
The recorded sequence of events.
Throws:
LoadingException If thrown while parsing.
java.io.IOException Should I/O error occur.
    return this.process(new InputSource(new StringReader(xml)));
  }

  
Runs the recorder on the specified input source.

Parameters:
is The input source.
Returns:
The recorded sequence of events.
Throws:
LoadingException If thrown whilst parsing.
java.io.IOException Should I/O error occur.
    if ( == null || ) {
      init();
    }
    try {
      .setFeature("http://xml.org/sax/features/namespaces"this..isNamespaceAware());
      .setFeature("http://xml.org/sax/features/namespace-prefixes"this..isReportPrefixDifferences());
      .parse(is);
    } catch (SAXException ex) {
      throw new LoadingException(ex);
    }
    return this.;
  }

  
Returns the configuration used by this recorder.

Returns:
the configuration used by this recorder.
  public DiffXConfig getConfig() {
    return this.;
  }

  
Sets the configuration used by this recorder.

Parameters:
config The configuration used by this recorder.
  public void setConfig(DiffXConfig config) {
    this. = config;
  }
  // other methods ------------------------------------------------------------------------------

  
Returns the name XMLReader class used by the SAXRecorders.

Returns:
the name XMLReader class used by the SAXRecorders.
  public static String getXMLReaderClass() {
    return ;
  }

  
Sets the name of the XML reader class to use.

Use null to reset the XML reader class and use the default XML reader.

A new reader will be created only if the specified class is different from the current one.

Parameters:
className The name of the XML reader class to use; or null to reset the XML reader.
  public static void setXMLReaderClass(String className) {
    // if the className is null reset to default
    if (className == null) {
      className = ;
    }
    // reload only if different from the current one.
     = !className.equals();
     = className;
  }

  
Initialises the XML reader using the defined class name.

Throws:
LoadingException If one of the features could not be set.
  private static void init() throws LoadingException {
    try {
       = XMLReaderFactory.createXMLReader();
      .setFeature("http://xml.org/sax/features/validation"false);
    } catch (SAXException ex) {
      throw new LoadingException(ex);
    }
  }
  // static inner class for processing the XML files --------------------------------------------

  
A SAX2 handler that records XML events.

This class is an inner class as there is no reason to expose its method to the public API.

Author(s):
Christophe Lauret, Jean-Baptiste Reure
Version:
27 April 2005
  private final class RecorderHandler extends DefaultHandler {

    
A buffer for character data.
    private final StringBuffer ch = new StringBuffer();

    
The comparator in order to sort attribute correctly.
    private final AttributeComparator comparator = new AttributeComparator();

    
The weight of the current element.
    private transient int currentWeight = -1;

    
The last open element event, should only contain OpenElementEvents.
    private transient List<OpenElementEventopenElements = new ArrayList<OpenElementEvent>();

    
The stack of weight, should only contain Integer.
    private transient List<Integerweights = new ArrayList<Integer>();

    
The factory that will produce events according to the configuration.
    private transient EventFactory efactory;

    
The text tokenizer according to the configuration.
    private transient TextTokenizer tokenizer;

    
    @Override
    public void startDocument() {
      SAXRecorder.this. = new EventSequence();
      this. = new EventFactory(SAXRecorder.this..isNamespaceAware());
      this. = TokenizerFactory.get(SAXRecorder.this.);
      SAXRecorder.this..mapPrefix("http://www.w3.org/XML/1998/namespace""xml");
    }

    
    @Override
    public void startPrefixMapping(String prefixString urithrows SAXException {
      SAXRecorder.this..mapPrefix(uriprefix);
    }

    
    @Override
    public void startElement(String uriString localNameString qNameAttributes atts) {
      recordCharacters();
      if (this. > 0) {
        this..add(new Integer(this.));
      }
      this. = 1;
      OpenElementEvent open = this..makeOpenElement(urilocalNameqName);
      this..add(open);
      SAXRecorder.this..addEvent(open);
      handleAttributes(atts);
    }

    
    @Override
    public void endElement(String uriString localNameString qName) {
      recordCharacters();
      OpenElementEvent open = popLastOpenElement();
      open.setWeight(this.);
      CloseElementEvent close = this..makeCloseElement(open);
      close.setWeight(this.);
      SAXRecorder.this..addEvent(close);
      // calculate weights
      this. += popWeight();
    }

    
    @Override
    public void characters(char[] bufint posint len) {
      this..append(bufposlen);
    }

    
    @Override
    public void ignorableWhitespace(char[] buf1int posint len) {
      // this method is only useful if the XML provides a Schema or DTD
      // to define in which cases whitespaces can be considered ignorable.
      // By default, all white spaces are significant and therefore reported
      // by the characters method.
    }

    
    @Override
    public void processingInstruction(String targetString data) {
      SAXRecorder.this..addEvent(new ProcessingInstructionEvent(targetdata));
      this.++;
    }

    
    @Override
    public void endDocument() throws SAXException {
    }

    
Records the characters which are in the buffer.
    private void recordCharacters() {
      if (this. != null) {
        List<TextEventevents = this..tokenize(this.);
        for (TextEvent e : events) {
          SAXRecorder.this..addEvent(e);
        }
        this. += events.size();
        this..setLength(0);
      }
    }

    
Returns the last open element and remove it from the stack.

Returns:
The last open element.
      return this..remove(this..size() - 1);
    }

    
Returns the last weight and remove it from the stack.

Returns:
The weight on top of the stack.
    private int popWeight() {
      if (this..size() > 0)
        return this..remove(this..size() - 1).intValue();
      else
        return 0;
    }

    
Handles the attributes, will add them to the sequence in order if any.

Parameters:
atts The attributes to handle.
    private void handleAttributes(Attributes atts) {
      // only one attribute
      if (atts.getLength() == 1) {
        SAXRecorder.this..addEvent(this..makeAttribute(atts.getURI(0),
            atts.getLocalName(0),
            atts.getQName(0),
            atts.getValue(0)));
        // several attributes
      } else if (atts.getLength() > 1) {
        // store all the attributes
        AttributeEvent[] attEvents = new AttributeEvent[atts.getLength()];
        for (int i = 0; i < atts.getLength(); i++) {
          attEvents[i] = this..makeAttribute(atts.getURI(i),
              atts.getLocalName(i),
              atts.getQName(i),
              atts.getValue(i));
          attEvents[i].setWeight(2);
          this. += 2;
        }
        // sort them
        Arrays.sort(attEventsthis.);
        // add them to the sequence
        for (AttributeEvent attEvent : attEvents) {
          SAXRecorder.this..addEvent(attEvent);
        }
      }
    }
  }

  
A tight error handler that will throw an exception for any error type. ErrorHandler used only so that namepsace related errors are reported ??? (they are error type and not fatal error).

Author(s):
Jean-baptiste Reure
Version:
17 May 2005
  private static final class RecorderErrorHandler implements ErrorHandler {

    
    public void error(SAXParseException exthrows SAXException {
      throw ex;
    }

    
    public void fatalError(SAXParseException exthrows SAXException {
      throw ex;
    }

    
    public void warning(SAXParseException exthrows SAXException {
      throw ex;
    }
  }
New to GrepCode? Check out our FAQ X