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()");
}
}
|