programming-examples/java/XML/Example XML server.java

135 lines
4.1 KiB
Java
Raw Normal View History

2019-11-15 12:59:38 +01:00
Example XML server
package project;
import java.util.Hashtable;
import org.w3c.dom.*;
import com.sun.xml.parser.Resolver;
import com.sun.xml.tree.*;
/**
* This servlet echoes or uppercases its input text. A more complex
* servlet might use a variety of server side state to perform its work,
* including databases (JDBC), the file system (including XML files),
* Enterprise JavaBeans (EJBs), Messaging Services (JMS), other web
* servers (perhaps in a business-to-business Extranet), and more.
*
* @version 1.3
*/
public class ExampleServlet extends XmlRpcServlet
{
private final static String exampleDtdFPI =
"+//Example DTD//foo//EN";
/**
* Arranges that input XML documents are parsed in a trivial
* "executable code" framework, and that resolving the DTD for
* the allowed input document type will not require network access.
*/
public ExampleServlet ()
{
SimpleElementFactory factory = new SimpleElementFactory ();
Hashtable bindings = new Hashtable (2);
Resolver resolver = new Resolver ();
//
// We push most of the work into customized DOM elements
//
bindings.put ("*Element", "project.ExampleServlet$Executable");
bindings.put ("uppercase", "project.ExampleServlet$Uppercase");
factory.addMapping (
"http://www.example.com/xml",
bindings,
getClass ().getClassLoader ());
customizeDocument (factory, false);
//
// We _really_ don't want to access the network to validate
// each document ... use its public ID to fetch a resource
//
resolver.registerCatalogEntry (exampleDtdFPI,
"project/example.dtd",
getClass ().getClassLoader ());
customizeResolver (resolver);
}
/**
* Modifies the input document, and returns it. The path info
* is unused.
*/
protected XmlDocument rpc (
String pathInfo,
XmlDocument request
)
{
TreeWalker walker = new TreeWalker (request);
Node node;
for (node = walker.getCurrent ();
node != null;
node = walker.getNext ()) {
if (node instanceof Executable)
((Executable)node).execute ();
// should report error if it's not an element type
// that we support ... but client will see an error
// when it validates, if we missed it!
}
// Ensure that the response is as valid as we can make it
request.setDoctype (exampleDtdFPI, "http://www.example.com/xml", null);
return request;
}
/**
* Base class for simple execution framework.
*/
static public class Executable extends ElementNode
{
/**
* In this simple framework, elements may optionally "execute"
* in an implicit context. The default implementation of this
* execution does nothing -- causing input to be echoed.
*
* <P> A more functional framework would pass explicit context
* in to the execution, so that more interesting work could
* be performed. For example, per-client session state will
* often be preserved, and the path info for the request will
* identify some particular object.
*/
public void execute ()
{
// Default implementation: does nothing
// Note that an explicit context (passed by argument)
// is often desirable (e.g. security or transaction
// context, parameters, etc)
}
}
/**
* Simple which, when executed, "uppercases" text (according
* to the rules used in the server's locale).
*/
static public class Uppercase extends Executable
{
/**
* This method's execution uppercases the content of its child
* text element.
*/
public void execute ()
{
// merge multiple text nodes ... and collapse space, unless
// requested otherwise
normalize ();
Text child = (Text) getFirstChild ();
if (child != null)
child.setData (child.getData ().toUpperCase ());
}
}
}