/* Copyright (c) 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.gdata.data.media; import com.google.gdata.util.common.base.Preconditions; import com.google.gdata.data.IEntry; import com.google.gdata.util.ContentType; import java.io.InputStream; import java.util.logging.Logger; import javax.activation.CommandInfo; import javax.activation.CommandMap; import javax.activation.MailcapCommandMap; import javax.mail.MessagingException; import javax.mail.internet.InternetHeaders; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMultipart; /** * The MediaMultipart class provides helper code for parsing and generating MIME * multipart/related content used to transport GData media resources. These * messages will always contains two parts: one with the Atom metadata about * the media and the other with the actual media content in any MIME format. * * */ public class MediaMultipart extends MimeMultipart { private static final Logger LOGGER = Logger.getLogger(MediaMultipart.class.getName()); static { loadMimeMappings(); } protected MediaBodyPart atomPart; protected MediaBodyPart mediaPart; /** * Loads the default set of Java activation MIME mappings required by * the GData library. Extends the basic set configured by the JavaMail * library to add mappings for Atom, RSS, and JSON application types. */ public static void loadMimeMappings() { final String[] CONTENT_TYPES = new String[] { "application/atom+xml", "application/rss+xml", "application/json" }; final String CONTENT_HANDLER = ";; x-java-content-handler" + "=com.google.gdata.data.media.GDataContentHandler"; CommandMap commandMap = CommandMap.getDefaultCommandMap(); if (commandMap instanceof MailcapCommandMap) { MailcapCommandMap mailcapMap = (MailcapCommandMap) commandMap; for (int i = 0; i < CONTENT_TYPES.length; i++) { CommandInfo[] comm = mailcapMap.getAllCommands(CONTENT_TYPES[i]); if (comm == null || comm.length == 0) { mailcapMap.addMailcap(CONTENT_TYPES[i] + CONTENT_HANDLER); } } } else { LOGGER.warning( "Unable to find MailcapCommandMap, skipping dynamic mailcap config."); } } /** * Constructor for subclasses. */ protected MediaMultipart(String subType) { super(subType); } /** * Constructs a new MediaMultipart instance by parsing MIME content from * the provided input stream. */ public MediaMultipart(String contentType, InputStream inputStream) throws MessagingException { // Construct a DataSource and pass it to the parent constructor. super(new MediaStreamSource(inputStream, contentType)); // Validate message content. if (getCount() != 2) { throw new MessagingException("Multipart must have Atom and media part"); } boolean atomFirst = getBodyPart(0).isMimeType(ContentType.ATOM.getMediaType()); if (!atomFirst && !getBodyPart(1).isMimeType(ContentType.ATOM.getMediaType())) { throw new MessagingException("No Atom MIME body part found"); } atomPart = (MediaBodyPart)getBodyPart(atomFirst ? 0 : 1); mediaPart = (MediaBodyPart)getBodyPart(atomFirst ? 1 : 0); } /** * Constructs a new MediaMultipart instance from an Atom entry instance * and a media source. */ public MediaMultipart(IEntry entry, MediaSource media) throws MessagingException { super("related"); Preconditions.checkNotNull(entry, "entry"); Preconditions.checkNotNull(media, "media"); atomPart = new MediaBodyPart(entry); addBodyPart(atomPart); mediaPart = new MediaBodyPart(media); addBodyPart(mediaPart); } @Override public MimeBodyPart createMimeBodyPart(InputStream is) throws MessagingException { return new MediaBodyPart(is); } @Override public MimeBodyPart createMimeBodyPart(InternetHeaders headers, byte [] content) throws MessagingException { return new MediaBodyPart(headers, content); } /** * Returns the body part containing atom content. */ public MediaBodyPart getAtomPart() { return atomPart; } /** * Returns the body part containing media content. */ public MediaBodyPart getMediaPart() { return mediaPart; } }