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; 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     }   } } 

This factory knows how to find only one kind of content handler, but 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.*; 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( );       }     }   } } 

Here's a typical run. As usual, tabs are indicated by arrows:

 %  java TabLoader http://www.ibiblio.org/javafaq/addresses.tab  JPE Associates  341 Lafayette Street, Suite 1025  New York  NY  10012 O'Reilly & Associates  103 Morris Street, Suite A  Sebastopol  CA  95472 

Java Network Programming
Java Network Programming, Third Edition
ISBN: 0596007213
EAN: 2147483647
Year: 2003
Pages: 164

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net