17.3 The ContentHandlerFactory Interface
A ContentHandlerFactory defines the rules for where
ContentHandler classes are stored. Create a class
that implements ContentHandlerFactory and give
this class a createContentHandler( ) method that
knows how to instantiate the right ContentHandler.
The createContentHandler( ) method should return
null if it can't find a
ContentHandler appropriate for a MIME type;
null signals Java to look for
ContentHandler classes in the default locations.
When the application starts, call the
URLConnection's
setContentHandlerFactory( ) method to set the
ContentHandlerFactory. This method may be called
only once in the lifetime of an application.
17.3.1 The createContentHandler( ) Method
Just as the createURLStreamHandler( ) method of
the URLStreamHandlerFactory interface was
responsible for finding and loading the appropriate protocol handler,
so too the createContentHandler() method of the
ContentHandlerFactory interface is responsible for
finding and loading the appropriate ContentHandler
given a MIME type:
public abstract ContentHandler createContentHandler(String mimeType)This method should be called only by the getContent() method of a URLConnection object. For
instance, Example 17-7 is a
ContentHandlerFactory that knows how to find the
right handler for the text/tab-separated-values
content handler of Example 17-1.
Example 17-7. TabFactory
package com.macfaq.net.www.content;This factory knows how to find only one kind of content handler, but
import java.net.*;
public class TabFactory implements ContentHandlerFactory {
public ContentHandler createContentHandler(String mimeType)) {
if (mimeType.equals("text/tab-separated-values") {
return new com.macfaq.net.www.content.text.tab_separated_values( );
}
else {
return null; // look for the handler in the default locations
}
}
}
there's no limit to how many a factory can know
about. For example, this createContentHandler( )
method also suggests handlers for
application/x-time, text/plain,
video/mpeg, and model/vrml.
Notice that when you're using a
ContentHandlerFactory, you don't
necessarily have to stick to standard naming conventions for
ContentHandler subclasses:
public ContentHandler createContentHandler(String mimeType)) {
if (mimeType.equals("text/tab-separated-values") {
return new com.macfaq.net.www.content.text.tab_separated_values( );
}
else if (mimeType.equals("application/x-time") {
return new com.macfaq.net.www.content.application.x_time( );
}
else if (mimeType.equals("text/plain") {
return new sun.net.www.content.text.plain( );
}
if (mimeType.equals("video/mpeg") {
return new com.macfaq.video.MPEGHandler( );
}
if (mimeType.equals("model/vrml") {
return new com.macfaq.threed.VRMLModel( );
}
else {
return null; // look for the handler in the default locations
}
}17.3.2 Installing Content Handler Factories
A ContentHandlerFactory is installed in an application
using the static URLConnection.setContentHandlerFactory() method:
public static void setContentHandlerFactory(ContentHandlerFactory fac)Note that this method is in the URLConnection
class, not the ContentHandler class. It may be
invoked at most once during any run of an application. It throws an
Error if it is called a second time.Using a ContentHandlerFactory such as the
TabFactory in Example 17-5, it's
possible to write a standalone application that can automatically
load the tab-separated-values content handler and that runs without
any major hassles with the class path. Example 17-8 is such a
program. However, as with most other setFactory( )
methods, untrusted, remotely loaded code such as an applet will
generally not be allowed to set the content handler factory.
Attempting to do so will throw a
SecurityException. Consequently, installing new
content handlers in applets pretty much requires directly accessing
the getContent( ) method of the
ContentHandler subclass itself. Ideally, this
shouldn't be necessary, but until Sun provides
better support for downloadable content handlers in browsers,
we're stuck with it.
Example 17-8. TabLoader that uses a ContentHandlerFactory
import java.io.*;Here's a typical run. As usual, tabs are indicated
import java.net.*;
import java.util.*;
import com.macfaq.net.www.content.*;
public class TabLoader {
public static void main (String[] args) {
URLConnection.setContentHandlerFactory(new TabFactory( ));
for (int i = 0; i < args.length; i++) {
try {
URL u = new URL(args[i]);
Object content = u.getContent( );
Vector v = (Vector) content;
for (Enumeration e = v.elements( ) ; e.hasMoreElements( ) ;) {
String[] sa = (String[]) e.nextElement( );
for (int j = 0; j < sa.length; j++) {
System.out.print(sa[j] + "\t");
}
System.out.println( );
}
}
catch (MalformedURLException ex) {
System.err.println(args[i] + " is not a good URL");
}
catch (Exception ex) {
ex.printStackTrace( );
}
}
}
}
by arrows:
% java TabLoader http://www.ibiblio.org/javafaq/addresses.tab
JPE Associates341 Lafayette Street, Suite 1025
New York
![]()
NY10012
O'Reilly & Associates103 Morris Street, Suite A
SebastopolCA
95472
• Table of Contents• Index• Reviews• Reader Reviews• Errata• AcademicJava Network Programming, 3rd EditionBy
Elliotte Rusty Harold Publisher: O'ReillyPub Date: October 2004ISBN: 0-596-00721-3Pages: 706
Thoroughly revised to cover all the 100+ significant updates
to Java Developers Kit (JDK) 1.5, Java Network
Programming is a complete introduction to
developing network programs (both applets and applications)
using Java, covering everything from networking fundamentals
to remote method invocation (RMI). It includes chapters on
TCP and UDP sockets, multicasting protocol and content
handlers, servlets, and the new I/O API. This is the
essential resource for any serious Java developer.