/**
* \package com.bluevia.android.messagery.mo.mms This package contains the classes in order to receive MMS using Bluevia API.
* \package com.bluevia.android.messagery.mo.mms.client This package contains REST client to receive MMS using Bluevia API.
*/
package com.bluevia.android.messagery.mo.mms.client;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import com.bluevia.android.commons.Encoding;
import com.bluevia.android.commons.Entity;
import com.bluevia.android.commons.Utils;
import com.bluevia.android.commons.connector.GenericResponse;
import com.bluevia.android.commons.exception.BlueviaException;
import com.bluevia.android.commons.exception.ConnectorException;
import com.bluevia.android.commons.parser.ParseException;
import com.bluevia.android.commons.parser.xml.BVRestXmlErrorParser;
import com.bluevia.android.commons.parser.xml.XmlConstants;
import com.bluevia.android.messagery.commons.parser.XmlMmsParser;
import com.bluevia.android.messagery.mo.client.BVMoClient;
import com.bluevia.android.messagery.mo.data.ReceivedMessageList;
import com.bluevia.android.messagery.mo.mms.data.MimeContent;
import com.bluevia.android.messagery.mo.mms.data.MmsMessage;
import com.bluevia.android.messagery.mo.mms.data.MmsMessageInfo;
import com.bluevia.android.messagery.mo.mms.parser.MultipartMmsParser;
/**
*
* Abstract client interface for the REST binding of the Bluevia MMS MO Service.
*
* @author Telefonica R&D
*
*/
public abstract class BVMoMmsClient extends BVMoClient {
private static final String ATTACHMENTS_FEED_PATH = "/attachments";
private MultipartMmsParser mMultipartParser;
/**
* Initializer of common attributes
*/
protected void init(){
mEncoding = Encoding.APPLICATION_XML;
mParser = new XmlMmsParser();
mMultipartParser = new MultipartMmsParser(mParser);
mSerializer = null; //No serializer
mErrorParser = new BVRestXmlErrorParser();
}
/**
*
* Retrieves the list of received messages without attachment ids.
*
* @see getAllMessages(String registrationId, boolean attachUrl)
*
* Note: the origin address of the received MMS will contain an alias, not a phone number.
*
* @param registrationId the registration id (short number) that receives the messages
* @return the list of messages.
* @throws BlueviaException
* @throws IOException
*/
public ArrayList<MmsMessageInfo> getAllMessages(String registrationId) throws BlueviaException, IOException{
return getAllMessages(registrationId, false);
}
/**
* Retrieves the list of received messages. Depending on the value of the useAttachmentsIds parameter, the response will
* include the IDs of the attachments or not.
* If the ids are retrieved, the function 'getAttachment' can be used; otherwise, the attachments must be obtained throught the getMessage function.
*
* @see getMessage(String registrationId, String messageId)
* @see getAttachment(String registrationId, String messageId, String attachmentId)
*
* Note: the origin address of the received MMS will contain an alias, not a phone number.
*
* @param registrationId the registration id (short number) that receives the messages
* @param attachUrl the boolean parameter to retrieve the IDs of the attachments or not
* @return the list of Received MMSs (list will be empty if the are no messages)
* @throws BlueviaException
* @throws IOException
*/
public ArrayList<MmsMessageInfo> getAllMessages(String registrationId, boolean attachUrl) throws BlueviaException, IOException{
ArrayList<MmsMessageInfo> receivedMmsList = null;
// Check params
checkRegistrationId(registrationId);
// Build feed uri for the request
String feedUri = "/" + registrationId + RECEIVED_MESSAGES;
HashMap<String, String> parameters = new HashMap<String, String>();
if (attachUrl)
parameters.put(XmlConstants.PARAM_USE_ATTACHMENT_URLS, "true");
parameters.put(XmlConstants.PARAM_VERSION_KEY, XmlConstants.VERSION_1);
Entity response = retrieve(feedUri, parameters);
receivedMmsList = getReceivedMmsListFromResponse(response);
return receivedMmsList;
}
/**
* Gets the received MMS list from the response Entity
*
* @param response response Entity that contains the result
* @return the received MMS list
* @throws BlueviaException if the response or the list are not valid.
*/
private ArrayList<MmsMessageInfo> getReceivedMmsListFromResponse(Entity response) throws BlueviaException{
ArrayList<MmsMessageInfo> receivedMmsList = null;
//If there are no messages, return empty list
if (response == null)
return new ArrayList<MmsMessageInfo>();
//Check if response is instance of ReceivedSmsList
if (!(response instanceof ReceivedMessageList))
throw new BlueviaException("Error during request. Response received does not correspond to a "
+ ReceivedMessageList.class.getName(), BlueviaException.INTERNAL_CLIENT_ERROR);
//Get received data
receivedMmsList = ((ReceivedMessageList)response).getList();
// Check list
if (receivedMmsList == null)
throw new BlueviaException(ReceivedMessageList.class.getName() + " object is null", BlueviaException.INTERNAL_CLIENT_ERROR);
return receivedMmsList;
}
/**
* Gets the content of a message with a 'messageId' sent to the 'registrationId'
*
* @param registrationId the registration id (short number) that receives the messages
* @param messageId the message id (obtained in getAllMessages function)
* @return the MmsMessage the complete MmsMessage (including attachments)
* @throws BlueviaException
* @throws IOException
*/
public MmsMessage getMessage(String registrationId, String messageId) throws BlueviaException, IOException{
// Check params
checkRegistrationId(registrationId);
if (Utils.isEmpty(messageId))
throw new BlueviaException("Bad request: Message identifier is either null or empty", BlueviaException.BAD_REQUEST_EXCEPTION);
// Build feed uri for the request
String feedUri = "/" + registrationId + RECEIVED_MESSAGES +
"/" + messageId;
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put(XmlConstants.PARAM_VERSION_KEY, XmlConstants.VERSION_1);
MmsMessage res = null;
InputStream is = null;
try {
String uri = mBaseUri + feedUri;
GenericResponse response = mConnector.retrieve(uri, parameters);
is = response.getAdditionalData().getBody();
HashMap<String, String> responseHeaders = response.getAdditionalData().getHeaders();
String contentType = responseHeaders.get("Content-Type");
ByteArrayDataSource ds = new ByteArrayDataSource(is, contentType);
MimeMultipart multipart = new MimeMultipart(ds);
res = mMultipartParser.parseMultipart(multipart);
} catch (ConnectorException e){
if (e.getAdditionalData().getBody() == null)
throw e;
else {
is = e.getAdditionalData().getBody();
String error = parseError(is);
String completeError = e.getMessage();
if (error != null)
completeError += ": " + error;
throw new ConnectorException(completeError, e.getCode());
}
} catch (MessagingException e) {
throw new ParseException("Unable to parse multpart", e);
} finally {
closeStream(is);
}
return res;
}
/**
*
* Gets the attachment with the specified id of the received message.
*
* @param registrationId the registration id (short number) that receives the messages
* @param messageId the message id (obtained in getAllMessages function)
* @param attachmentId the attachment id (obtained in getAllMessages function)
* @return the attachment of the received MMS.
* @throws BlueviaException
* @throws IOException
*/
public MimeContent getAttachment(String registrationId, String messageId, String attachmentId) throws BlueviaException, IOException {
// Check params
checkRegistrationId(registrationId);
if (Utils.isEmpty(messageId))
throw new BlueviaException("Bad request: Message identifier is either null or empty", BlueviaException.BAD_REQUEST_EXCEPTION);
if (Utils.isEmpty(attachmentId))
throw new BlueviaException("Bad request: Attachment identifier is either null or empty", BlueviaException.BAD_REQUEST_EXCEPTION);
// Build feed uri for the request
String feedUri = "/" + registrationId +
RECEIVED_MESSAGES + "/" + messageId +
ATTACHMENTS_FEED_PATH + "/" + attachmentId;
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put(XmlConstants.PARAM_VERSION_KEY, XmlConstants.VERSION_1);
Entity res = null;
InputStream is = null;
try {
String uri = mBaseUri + feedUri;
GenericResponse response = mConnector.retrieve(uri, parameters);
is = response.getAdditionalData().getBody();
HashMap<String, String> responseHeaders = response.getAdditionalData().getHeaders();
String contentType = responseHeaders.get("Content-Type");
String contentDisp = responseHeaders.get("Content-Disposition");
if (contentType.contains("xml") || contentType.contains("smil") || contentType.contains("text"))
res = mMultipartParser.buildMimeContent(contentType, contentDisp, Utils.convertStreamToString(is), true);
else res = mMultipartParser.buildMimeContent(contentType, contentDisp, is, true);
} catch (ConnectorException e){
if (e.getAdditionalData().getBody() == null)
throw e;
else {
is = e.getAdditionalData().getBody();
String error = parseError(is);
String completeError = e.getMessage();
if (error != null)
completeError += ": " + error;
throw new ConnectorException(completeError, e.getCode());
}
} finally {
closeStream(is);
}
if (res == null || !(res instanceof MimeContent))
throw new BlueviaException("Error during request. Response received does not correspond to a "
+ MimeContent.class.getName(), BlueviaException.INTERNAL_CLIENT_ERROR);
return (MimeContent) res;
}
}