callfilter.java

来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· Java 代码 · 共 240 行

JAVA
240
字号
/* * Copyright (C) 1999-2001 David Brownell *  * This file is part of GNU JAXP, a library. * * GNU JAXP is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *  * GNU JAXP is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * As a special exception, if you link this library with other files to * produce an executable, this library does not by itself cause the * resulting executable to be covered by the GNU General Public License. * This exception does not however invalidate any other reasons why the * executable file might be covered by the GNU General Public License.  */package gnu.xml.pipeline;import java.io.*;import java.net.*;import org.xml.sax.*;import org.xml.sax.ext.*;import org.xml.sax.helpers.XMLReaderFactory;import gnu.xml.util.Resolver;import gnu.xml.util.XMLWriter;/** * Input is sent as an XML request to given URI, and the output of this * filter is the parsed response to that request. * A connection is opened to the remote URI when the startDocument call is * issued through this filter, and the request is finished when the * endDocument call is issued.  Events should be written quickly enough to * prevent the remote HTTP server from aborting the connection due to * inactivity; you may want to buffer text in an earlier pipeline stage. * If your application requires validity checking of such * outputs, have the output pipeline include a validation stage. * * <p>In effect, this makes a remote procedure call to the URI, with the * request and response document syntax as chosen by the application. * <em>Note that all the input events must be seen, and sent to the URI, * before the first output event can be seen. </em>  Clients are delayed * at least by waiting for the server to respond, constraining concurrency. * Services can thus be used to synchronize concurrent activities, and * even to prioritize service among different clients. * * <p> You are advised to avoid restricting yourself to an "RPC" model * for distributed computation.  With a World Wide Web, network latencies * and failures (e.g. non-availability) * are significant; adopting a "procedure" model, rather than a workflow * model where bulk requests are sent and worked on asynchronously, is not * generally an optimal system-wide architecture.  When the messages may * need authentication, such as with an OpenPGP signature, or when server * loads don't argue in favor of immediate responses, non-RPC models can * be advantageous.  (So-called "peer to peer" computing models are one * additional type of model, though too often that term is applied to * systems that still have a centralized control structure.) * * <p> <em>Be strict in what you send, liberal in what you accept,</em> as * the Internet tradition goes.  Strictly conformant data should never cause * problems to its receiver; make your request pipeline be very strict, and * don't compromise on that.  Make your response pipeline strict as well, * but be ready to tolerate specific mild, temporary, and well-documented * variations from specific communications peers. * * @see XmlServlet * * @author David Brownell */final public class CallFilter implements EventConsumer{    private Requestor			req;    private EventConsumer		next;    private URL				target;    private URLConnection		conn;    private ErrorHandler		errHandler;    /**     * Initializes a call filter so that its inputs are sent to the     * specified URI, and its outputs are sent to the next consumer     * provided.     *     * @exception IOException if the URI isn't accepted as a URL     */	// constructor used by PipelineFactory    public CallFilter (String uri, EventConsumer next)    throws IOException    {	this.next = next;	req = new Requestor ();	setCallTarget (uri);    }    /**     * Assigns the URI of the call target to be used.     * Does not affect calls currently being made.     */    final public void setCallTarget (String uri)    throws IOException    {	target = new URL (uri);    }    /**     * Assigns the error handler to be used to present most fatal     * errors.     */    public void setErrorHandler (ErrorHandler handler)    {	req.setErrorHandler (handler);    }    /**     * Returns the call target's URI.     */    final public String getCallTarget ()    {	return target.toString ();    }    /** Returns the content handler currently in use. */    final public org.xml.sax.ContentHandler getContentHandler ()    {	return req;    }    /** Returns the DTD handler currently in use. */    final public DTDHandler getDTDHandler ()    {	return req;    }    /**     * Returns the declaration or lexical handler currently in     * use, or throws an exception for other properties.     */    final public Object getProperty (String id)    throws SAXNotRecognizedException    {	if (EventFilter.DECL_HANDLER.equals (id))	    return req;	if (EventFilter.LEXICAL_HANDLER.equals (id))	    return req;	throw new SAXNotRecognizedException (id);    }    // JDK 1.1 seems to need it to be done this way, sigh    ErrorHandler getErrorHandler () { return errHandler; }    //    // Takes input and echoes to server as POST input.    // Then sends the POST reply to the next pipeline element.    //    final class Requestor extends XMLWriter    {	Requestor ()	{	    super ((Writer)null);	}	public synchronized void startDocument () throws SAXException	{	    // Connect to remote object and set up to send it XML text	    try {		if (conn != null)		    throw new IllegalStateException ("call is being made");		conn = target.openConnection ();		conn.setDoOutput (true);		conn.setRequestProperty ("Content-Type",			    "application/xml;charset=UTF-8");		setWriter (new OutputStreamWriter (			conn.getOutputStream (),			"UTF8"), "UTF-8");	    } catch (IOException e) {		fatal ("can't write (POST) to URI: " + target, e);	    }	    // NOW base class can safely write that text!	    super.startDocument ();	}	public void endDocument () throws SAXException	{	    //	    // Finish writing the request (for HTTP, a POST);	    // this closes the output stream.	    //	    super.endDocument ();	    //	    // Receive the response.	    // Produce events for the next stage.	    //	    InputSource	source;	    XMLReader	producer;	    String	encoding;	    try {		source = new InputSource (conn.getInputStream ());// FIXME if status is anything but success, report it!!  It'd be good to// save the request data just in case we need to deal with a forward.		encoding = Resolver.getEncoding (conn.getContentType ());		if (encoding != null)		    source.setEncoding (encoding);		producer = XMLReaderFactory.createXMLReader ();		producer.setErrorHandler (getErrorHandler ());		EventFilter.bind (producer, next);		producer.parse (source);		conn = null;	    } catch (IOException e) {		fatal ("I/O Exception reading response, " + e.getMessage (), e);	    }	}    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?