/** * \package com.bluevia.messagery.mt.mms This package contains the classes in order to semd MMS using Bluevia API. * \package com.bluevia.messagery.mt.mms.client This package contains REST client to send MMS using Bluevia API. */ package com.bluevia.messagery.mt.mms.client; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashMap; import org.apache.log4j.Logger; import com.bluevia.commons.Encoding; import com.bluevia.commons.Entity; import com.bluevia.commons.Utils; import com.bluevia.commons.connector.GenericResponse; import com.bluevia.commons.connector.http.multipart.BlueviaPartBase; import com.bluevia.commons.connector.http.multipart.FilePart; import com.bluevia.commons.connector.http.multipart.PartContainer; import com.bluevia.commons.connector.http.multipart.StringPart; import com.bluevia.commons.data.JaxbEntity; import com.bluevia.commons.exception.BlueviaException; import com.bluevia.commons.exception.ConnectorException; import com.bluevia.commons.parser.xml.XmlConstants; import com.bluevia.commons.parser.xml.XmlParser; import com.bluevia.commons.parser.xml.XmlSerializer; import com.bluevia.messagery.mt.client.BVMtClient; import com.bluevia.messagery.mt.data.DeliveryInfo; import com.bluevia.messagery.mt.data.DeliveryInfoList; import com.bluevia.messagery.mt.mms.data.Attachment; import com.bluevia.messagery.mt.mms.data.MmsMessageReq; import com.bluevia.messagery.mt.mms.data.Attachment.ContentType; import com.telefonica.schemas.unica.rest.mms.v1.MessageDeliveryStatusType; /** * * Abstract client interface for the REST binding of the Bluevia MMS MT Service. * * @author Telefonica R&D * */ public abstract class BVMtMmsClient extends BVMtClient { private static Logger log = Logger.getLogger(BVMtMmsClient.class.getName()); /** * Initializer for common attributes */ protected void init(){ mEncoding = Encoding.APPLICATION_XML; mParser = new XmlParser(); mSerializer = new XmlSerializer(); } /** * * Allows to know the delivery status of a previous sent MMS using Bluevia API * @param mmsId the id of the mms previously sent using this API * @param payer the payer * @return the delivery status of the MMS message id * @throws BlueviaException * @throws IOException */ protected String sendMms(MmsMessageReq mmsMessage, String payer) throws BlueviaException, IOException { String result = null; checkMessage(mmsMessage); GenericResponse response = null; InputStream is = null; try { JaxbEntity messageEntity= new JaxbEntity(); messageEntity.setJcInstance(XmlConstants.XSD_MMS_API_INSTANCE); messageEntity.setNamespace(XmlConstants.NS_MMS_API_URI); messageEntity.setQname(XmlConstants.XSD_MMSTEXTTYPE_MMSMESSAGE); messageEntity.setObject(mmsMessage.toMessageType()); byte[] bytes = serializeEntity(messageEntity); BlueviaPartBase[] parts = buildMultipart(mmsMessage, bytes); String uri = mBaseUri; HashMap<String, String> params = new HashMap<String, String>(); params.put(XmlConstants.PARAM_VERSION_KEY, XmlConstants.VERSION_1); HashMap<String, String> headers = new HashMap<String, String>(); if (!Utils.isEmpty(payer)) { headers.put(HEADER_X_CHARGED_ID, payer); } response = mConnector.create(uri, params, parts, headers); is = response.getAdditionalData().getBody(); result = getMesageIdFromResponse(response.getAdditionalData().getHeaders(), uri); } catch (ConnectorException e){ if (e.getAdditionalData().getBody() == null) throw e; else { is = e.getAdditionalData().getBody(); String error = parseError(is); throw new ConnectorException(error, e.getCode()); } } finally { //Close the stream if (is != null) try { is.close(); } catch (IOException e) { log.info(e.getMessage(), e); } } return result; } /** * Build a multipart Part Base adapted to Bluevia * * @param message * @return * @throws BlueviaException * @throws IOException */ private BlueviaPartBase[] buildMultipart(MmsMessageReq message, byte[] serializedRoots) throws BlueviaException, IOException { String entryString = new String(serializedRoots, "UTF-8"); //Build root-field StringPart rootField = new StringPart("root-fields", entryString); switch (mEncoding) { case APPLICATION_XML: rootField.setContentType(BlueviaPartBase.APPLICATION_XML); break; case APPLICATION_JSON: rootField.setContentType(BlueviaPartBase.APPLICATION_JSON); break; case APPLICATION_URL_ENCODED: rootField.setContentType(BlueviaPartBase.APPLICATION_URL_ENCODED); } BlueviaPartBase[] multipart = new BlueviaPartBase[2]; multipart[0] = rootField; ArrayList<Attachment> attachmentList = message.getAttachementList(); int partssize= 1; // for adding message Text to parts if (attachmentList!=null) { partssize+= attachmentList.size(); } BlueviaPartBase[] parts = new BlueviaPartBase[partssize]; StringPart textPart= new StringPart("message.txt", message.getTextMessage()); textPart.setFilename(textPart.getName()); parts[0]= (StringPart) textPart; parts[0].setName("attachment"); parts[0].setContentDisposition("form-data"); for (int i=1; i<partssize; i++) { int index= i - 1; File file= new File(attachmentList.get(index).getFilePath()); FilePart attach= new FilePart(file.getName(), file, attachmentList.get(index).getStringContentType()); // Text encondig (from user system default encoding to utf-8) for text/plain if (attachmentList.get(index).getStringContentType().equals(BlueviaPartBase.TEXT_PLAIN)) { FileInputStream filein= new FileInputStream(file); ByteArrayOutputStream os= new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int len; while ((len = filein.read(buf)) > 0) { os.write(buf, 0, len); } filein.close(); String fileText = null; fileText = new String(os.toString(Charset.defaultCharset().displayName())); StringPart textPlainPart= new StringPart(attachmentList.get(index).getFilePath(), fileText); textPlainPart.setFilename(textPlainPart.getName()); parts[i]= (StringPart) textPlainPart; parts[i].setName("attachment"); parts[i].setContentDisposition("form-data"); } else { parts[i]= attach; parts[i].setName("attachment"); parts[i].setContentDisposition("form-data"); } } PartContainer part_container = new PartContainer("attachments", parts); multipart[1] = part_container; return multipart; } /** * Adds the message parameter as a string attachment * * @param message * @param attachmentList * @throws IOException */ protected void addMessageToAttachments(String message, ArrayList<Attachment> attachmentList) throws IOException{ if (!Utils.isEmpty(message)){ if (attachmentList == null) { attachmentList = new ArrayList<Attachment>(); } attachmentList.add(new Attachment("message.txt", ContentType.TEXT_PLAIN)); } } /** * * Allows to know the delivery status of a previous sent message using Bluevia API * * @param messageId the id of the message previously sent using this API * @return an arrayList containing the DeliveryInfo for each destination address from the sent message. * @throws BlueviaException * @throws IOException * */ public ArrayList<DeliveryInfo> getDeliveryStatus(String messageId) throws BlueviaException, IOException { ArrayList<DeliveryInfo> status = null; if (Utils.isEmpty(messageId)) throw new BlueviaException("Bad request: messageId is either null or empty", BlueviaException.BAD_REQUEST_EXCEPTION); //Build the status feed uri String feedUri = "/" + messageId + DELIVERY_STATUS_PATH; HashMap<String, String> parameters = new HashMap<String, String>(); parameters.put(XmlConstants.PARAM_VERSION_KEY, XmlConstants.VERSION_1); ((XmlParser) mParser).setParseClass(MessageDeliveryStatusType.class); Entity response = retrieve(feedUri, parameters); //Check if response is instance of JaxbEntity if ((response == null) || (! (response instanceof JaxbEntity))) throw new BlueviaException("Error during request. Response received does not correspond to an DeliveryInfo", BlueviaException.INTERNAL_CLIENT_ERROR); JaxbEntity parseEntity= (JaxbEntity) response; //Check if parseEntity is instance of MessageDeliveryStatusType MessageDeliveryStatusType deliveryStatusType= new MessageDeliveryStatusType(); if ((parseEntity.getObject() == null) || (! (parseEntity.getObject() instanceof MessageDeliveryStatusType))) throw new BlueviaException("Error during request. Response received does not correspond to an DeliveryInfo", BlueviaException.INTERNAL_CLIENT_ERROR); deliveryStatusType = (MessageDeliveryStatusType) parseEntity.getObject(); log.debug("Creating response List of DeliveryInfo"); Entity retEntity = new DeliveryInfoList(deliveryStatusType); //Check if response is instance of DeliveryInfo if ((retEntity == null) || (! (retEntity instanceof DeliveryInfoList))) throw new BlueviaException("Error during request. Response received does not correspond to an DeliveryInfo", BlueviaException.INTERNAL_CLIENT_ERROR); //Set the response status = ((DeliveryInfoList) retEntity).getDeliveryStatusList(); if (status.isEmpty()) throw new BlueviaException("The DeliveryInfo received is empty", BlueviaException.INTERNAL_CLIENT_ERROR); return status; } }