FileDocCategorySizeDatePackage
EBookServiceServant.javaAPI DocExample6689Wed Mar 12 00:09:14 GMT 2003ora.jwsnut.chapter6.extendedbookservice

EBookServiceServant.java

package ora.jwsnut.chapter6.extendedbookservice;

import java.awt.Component;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

/**
 * Implementation class for the extended books web service.
 */
public class EBookServiceServant implements EBookQuery {
    
    /**
     * MediaTracker used to load images
     */
    private MediaTracker tracker;
    
    /**
     * Gets the number of books known to the service
     * @return the number of books known to the service.
     */
    public int getBookCount() {
        String[] titles = EBookServiceServantData.getBookTitles();
        return titles == null ? 0 : titles.length;
    }

    /**
     * Gets the set of book titles.
     * @return the set of book titles.
     */
    public String[] getBookTitles() {
        return EBookServiceServantData.getBookTitles();        
    }
    
    /**
     * Gets the images for a books with given titles
     * @param titles the titles of the books
     * @param gif <code>true</code> to request a GIF, <code>false</code> for JPEG
     * @return an array of images for the named books.
     * @throws EBookServiceException if any book title is unknown
     */
    public Image[] getImages(String[] titles, boolean gif) throws EBookServiceException {
        int length = titles.length;
        Image[] images = new Image[length];
        for (int i = 0; i < length; i++) {
            byte[] imageData = EBookServiceServantData.getImageData(titles[i], gif);
            if (imageData == null) {
                throw new EBookServiceException("Unknown title: [" + titles[i] + "]");
            }
            if (tracker == null) {
                tracker = new MediaTracker(new Component() {});
            }
            Image image = Toolkit.getDefaultToolkit().createImage(imageData);
            tracker.addImage(image, 0);
            images[i] = image;            
        }
        try {
            tracker.waitForAll();
            for (int i = 0; i < length; i++) {
                tracker.removeImage(images[i]);
            }
        } catch (InterruptedException ex) {
        }

        return images;
    }

    /**
     * Gets book images in the form of a DataHandler
     * @param titles the titles of the books
     * @param gif <code>true</code> to request GIF, <code>false</code> for JPEG
     * @return an array of DataHandlers for the cover images for the named books.
     * @throws EBookServiceException if any book title is unknown
     */
    public DataHandler[] getImageHandlers(String[] titles, boolean gif) throws EBookServiceException {
        int length = titles.length;
        DataHandler[] handlers = new DataHandler[length];
        for (int i = 0; i < length; i++) {
            byte[] imageData = EBookServiceServantData.getImageData(titles[i], gif);
            if (imageData == null) {
                throw new EBookServiceException("Unknown title: [" + titles[i] + "]");
            }
            handlers[i] = new DataHandler(new ByteArrayDataSource("Image Data",
                                            imageData,
                                            gif ? "image/gif" : "image/jpeg"));
        }
        return handlers;
    }

    /**
     * Gets the book images in MimeMultipart form
     * @return a MimeMultipart object containing the book images.
     */
    public MimeMultipart getAllImages() throws EBookServiceException {
        String[] titles = EBookServiceServantData.getBookTitles();
        Image[] images = getImages(titles, false);
        
        try {
            MimeMultipart mp = new MimeMultipart();
            for (int i = 0; i < images.length; i++) {
                MimeBodyPart mbp = new MimeBodyPart();
                mbp.setContent(images[i], "image/jpeg");
                mbp.addHeader("Content-Type", "image/jpeg");
                mp.addBodyPart(mbp);
            }          
            return mp;
        } catch (MessagingException ex) {
            throw new EBookServiceException("Failed building MimeMultipart: " + ex.getMessage());
        }
    }
    
    /**
     * Gets XML details for a given list of books.
     * @param titles the titles of the books.
     * @return an array of Source object containing XML details for
     * the given list of books.
     * @throws EBookServiceException if the book title is unknown
     */
    public Source[] getBookDetails(String[] titles) throws EBookServiceException {
        int length = titles.length;
        Source[] sources = new Source[length];
        
        for (int i = 0; i < length; i++) {
            String data = EBookServiceServantData.getXMLDetails(titles[i]);
            if (data == null) {
                throw new EBookServiceException("Unknown title: [" + titles[i] + "]");
            }
            try {
                data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + data;
                sources[i] = new StreamSource(new ByteArrayInputStream(data.getBytes("utf-8"))); 
            } catch (UnsupportedEncodingException ex) {
                ex.printStackTrace();
            }         
        }
        
        return sources;
    }    
}

/**
 * A private DataSource implementation that
 * allows byte streams of arbitrary types to
 * be associated with a DataHandler.
 */
class ByteArrayDataSource implements DataSource {

    private String contentType;
    
    private byte[] data; 
    
    private String name;
        
    ByteArrayDataSource(String name, byte[] data, String contentType) {
        this.name = name;
        this.data = data;
        this.contentType = contentType;
    }
    
    public String getContentType() {
        return contentType;
    }
    
    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(data);
    }
    
    public String getName() {
        return name;
    }
    
    public OutputStream getOutputStream() throws IOException {
        throw new IOException("ByteArrayDataSource cannot support getOutputStream()");
    }
}