[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Issue 5.1) SSH End of message directive




Please forgive the nature of the attached Java code as it has a number of hacks; however, it will parse a document containing an XML "forest" (set of trees) using org.apache.crimson.parser.XMLReaderImpl. Perhaps there's a less ugly way to do this with instances of PipedReader/Writer ...

(The way that it works is to provide a FileReader that only
returns a line at a time to the SAX parser no matter how
much it requests in the read().  Then, when reading is aborted
from within the handler, the position in the input stream
is legitimate.  Over-riding close() is a total hack, but
could possibly be replaced with a strategy using pipes.)

I'm not saying this code is wonderful and there is no need for
framing ... I just want to ensure that we aren't being swayed
too much by short-term implementation issues.  After all,
I like the idea of being able to paste XML snippets into SSH
without too much "noise".

On Dec 5, 2003, at 1:19 PM, Phil Shafer wrote:
Juergen Schoenwaelder writes:
Does everybody feel comfortable to be required to feed the protocol
message directly into an XML parser using a SAX like interface in
order to detect message boundaries?

We've had problems doing this esp in java.

I have to agree now ... at the interim, you said that you were using SAX, and I thought of the C implementation "expat", where it's not too bad. It's very unpleasant in Java, as the attached code illustrates.

Furthermore, I believe that declarations add value in the long run
and we should not forbit declarations of PIs.

Declarations make an xml parser a couple of orders of magnitude harder to write and at least a couple of orders of magnitude larger. Given the diminishing value and use of DTDs, I don't see the win.

If you do need the features of DTDs, you can preprocess your document
on an external machine and pass the expanded DTD-less data to the
netconf server.


What mechanism do you suggest, then?  The framing that
we currently have for SSH uses the processing instruction
<?eom?>

(I would suggest that DTDs should even be eliminated from the XML
specification ...)

Ted.



import org.xml.sax.*;
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.helpers.DefaultHandler;
import java.io.*;


public class ForestReader extends DefaultHandler {


  private XMLReader parser;
  private Writer out;

  public ForestReader(XMLReader parser, Writer out) {
    this.parser = parser;
    this.out = out;
  }

  private void output(String s) throws SAXException {
    try {
      out.write(s);
      out.flush();
    }
    catch (IOException e) {
      throw new SAXException("Nested IOException", e);
    }
  }

  public void startElement(String namespaceURI, String localName,
   String qualifiedName, Attributes atts) throws SAXException {
    this.output("start element " + qualifiedName + "\n");
  }

  public void endElement(String namespaceURI, String localName,
   String qualifiedName) throws SAXException {
   this.output("end element " + qualifiedName + "\n");
   if ("rpc" == qualifiedName)  {
       this.output("RPC found\n");
       throw new SAXDocumentCompleteException("\nRPC found.");
   }
  }



  public static void main(String[] args) {
      boolean keepReading = true;

      if (args.length <= 0) {
        System.out.println(
       "Usage: java ForestReader url"
      );
      return;
    }

    try {
      XMLReader parser = XMLReaderFactory.createXMLReader();

      Writer out = new OutputStreamWriter(System.out);
      Object handler = new ForestReader(parser, out);
      parser.setContentHandler((ContentHandler) handler);

      DurableFileReader duraread = new DurableFileReader(args[0]);
      InputSource input = new InputSource(duraread);
      int c;


while (keepReading) { try { parser.parse(input); } catch (SAXDocumentCompleteException e) { System.out.println(e); } }

      duraread.delayedClose();
      out.flush();
      out.close();
    }
    catch (Exception e) {
      System.err.println(e);
    }

}

}




class DurableFileReader extends FileReader {


public DurableFileReader(String filename) throws FileNotFoundException {
super(filename);
}


    public void close()  throws IOException  {
    }

    public void delayedClose()  throws IOException {
        super.close();
    }
    public int read() throws java.io.IOException {
        return super.read();
    }
    public int read(char[] array) throws java.io.IOException {
        return super.read(array);
    }

public int read(char[] array, int offset, int len) throws java.io.IOException {
int max = array.length;
int i;


        for (i = offset; i < max; i++)  {
            array[i] = (char) super.read();
            if ('\n' == array[i])  {
                break;
            }
        }
        return ((i - offset) + 1);
    }

}



class SAXDocumentCompleteException extends SAXException {
    public SAXDocumentCompleteException(String s) {
        super(s);
    }
    public SAXDocumentCompleteException(Exception e) {
        super(e);
    }
    public SAXDocumentCompleteException(String s, Exception e) {
        super(s, e);
    }
}




-- to unsubscribe send a message to netconf-request@ops.ietf.org with the word 'unsubscribe' in a single line as the message text body. archive: <http://ops.ietf.org/lists/netconf/>