Source Code Cross Referenced for MultipartObject.java in  » 6.0-JDK-Modules » j2me » com » sun » tck » wma » mms » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » com.sun.tck.wma.mms 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *   
0003:         *
0004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006:         * 
0007:         * This program is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU General Public License version
0009:         * 2 only, as published by the Free Software Foundation.
0010:         * 
0011:         * This program is distributed in the hope that it will be useful, but
0012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014:         * General Public License version 2 for more details (a copy is
0015:         * included at /legal/license.txt).
0016:         * 
0017:         * You should have received a copy of the GNU General Public License
0018:         * version 2 along with this work; if not, write to the Free Software
0019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA
0021:         * 
0022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023:         * Clara, CA 95054 or visit www.sun.com if you need additional
0024:         * information or have any questions.
0025:         */
0026:
0027:        package com.sun.tck.wma.mms;
0028:
0029:        // Interfaces
0030:        import com.sun.tck.wma.MessageConnection;
0031:
0032:        // Classes
0033:        import com.sun.tck.wma.MessagePart;
0034:        import com.sun.tck.wma.MultipartMessage;
0035:        import com.sun.tck.wma.sms.MessageObject;
0036:        import java.io.ByteArrayInputStream;
0037:        import java.io.ByteArrayOutputStream;
0038:        import java.io.DataInputStream;
0039:        import java.io.DataOutputStream;
0040:        import java.util.Date;
0041:        import java.util.Vector;
0042:
0043:        // Exceptions
0044:        import com.sun.tck.wma.SizeExceededException;
0045:        import java.io.IOException;
0046:
0047:        /**
0048:         * Implements an MMS message for the MMS message connection.
0049:         */
0050:        public class MultipartObject extends MessageObject implements 
0051:                MultipartMessage {
0052:
0053:            /** The array of "to" addresses. */
0054:            Vector to;
0055:            /** The array of "cc" addresses. */
0056:            Vector cc;
0057:            /** The array of "bcc" addresses. */
0058:            Vector bcc;
0059:            /** The array of message parts. */
0060:            Vector parts;
0061:            /** The Content-ID of the part that starts the message. */
0062:            String startContentID;
0063:            /** The Subject field of the message. */
0064:            String subject;
0065:            /** The array of message headers. */
0066:            String[] headerValues;
0067:            /** The Application Identifier of the agent to process the message. */
0068:            String applicationID;
0069:            /** 
0070:             * The Application Identifier of the return agent to 
0071:             * process the message.
0072:             */
0073:            String replyToApplicationID;
0074:
0075:            /** 
0076:             * Construct a multipart message and initialize the  
0077:             * target address. 
0078:             * @param toAddress the address of the recipient. May be null. 
0079:             */
0080:            public MultipartObject(String toAddress) {
0081:                super (MessageConnection.MULTIPART_MESSAGE, null);
0082:                to = new Vector();
0083:                cc = new Vector();
0084:                bcc = new Vector();
0085:                parts = new Vector();
0086:                startContentID = null;
0087:                subject = null;
0088:                applicationID = null;
0089:                replyToApplicationID = null;
0090:                setupHeaderFields();
0091:                if (toAddress != null) {
0092:                    addAddress("to", toAddress);
0093:                }
0094:            }
0095:
0096:            /**
0097:             * Gets the "reply-to" application identifier.
0098:             * @return the return address application identifier, or null if none is set
0099:             * @see #setReplyToApplicationID
0100:             */
0101:            String getReplyToApplicationID() {
0102:                return replyToApplicationID;
0103:            }
0104:
0105:            /**
0106:             * Sets the "reply-to" application identifier.
0107:             * @param appID the return address application identifier. May be null.
0108:             * @see #getReplyToApplicationID
0109:             */
0110:            public void setReplyToApplicationID(String appID) {
0111:                replyToApplicationID = appID;
0112:            }
0113:
0114:            /**
0115:             * Returns the destination application identifier.
0116:             * @return the destination application identifier, or null if none is set
0117:             */
0118:            public String getApplicationID() {
0119:                return applicationID;
0120:            }
0121:
0122:            /**
0123:             * Sets the "from" address.
0124:             * @param fromAddress the return address, which may be null
0125:             */
0126:            public void setFromAddress(String fromAddress) {
0127:                super .setAddress(fromAddress);
0128:            }
0129:
0130:            /**
0131:             * Prepares a received message to be sent right back to the sender.
0132:             * Removes this device's address from the "to" and "cc"
0133:             * address lists and sets the sender's address as the first "to" address.
0134:             * @param senderAddress the sender's address. Should not include the 
0135:             *      <code>"mms://"</code> prefix, and may contain the 
0136:             *      <code>":appID"</code> suffix. May be null.
0137:             * @param myAddress this device's address. Must not be null. 
0138:             */
0139:            public void fixupReceivedMessageAddresses(String senderAddress,
0140:                    String myAddress) {
0141:                String regularAddress = myAddress;
0142:                String plusAddress = myAddress;
0143:                if (regularAddress.charAt(0) == '+') {
0144:                    regularAddress = regularAddress.substring(1);
0145:                } else if (plusAddress.charAt(0) != '+') {
0146:                    plusAddress = "+" + plusAddress;
0147:                }
0148:                // remove ourselves from "to" and "cc" list
0149:                Vector addresses = to;
0150:                for (int i = 0; i < 2; ++i) {
0151:                    int numAdds = addresses.size();
0152:                    for (int index = 0; index < numAdds; ++index) {
0153:                        String this Address = (String) addresses
0154:                                .elementAt(index);
0155:                        MMSAddress parsedAddress = MMSAddress
0156:                                .getParsedMMSAddress(this Address);
0157:                        if (parsedAddress != null
0158:                                && (regularAddress
0159:                                        .equals(parsedAddress.address) || plusAddress
0160:                                        .equals(parsedAddress.address))) {
0161:                            --numAdds;
0162:                            addresses.removeElementAt(index);
0163:                            --index;
0164:                        }
0165:                    }
0166:                    addresses = cc;
0167:                }
0168:                // set the first "to" address to be the sender's address
0169:                if (senderAddress != null) {
0170:                    String formalAddress = senderAddress;
0171:                    to.insertElementAt(formalAddress, 0);
0172:                    MMSAddress parsedAddress = MMSAddress
0173:                            .getParsedMMSAddress(formalAddress);
0174:                    applicationID = parsedAddress.appId;
0175:                } else {
0176:                    applicationID = null;
0177:                }
0178:            }
0179:
0180:            /**
0181:             * Gets the requested address list.
0182:             *
0183:             * @param type the address list to be returned, either "to", "cc" or "bcc" 
0184:             * @exception IllegalArgumentException if some other 
0185:             * address list type is requested
0186:             * @return a list of addresses
0187:             */
0188:            Vector getAddressList(String type) {
0189:                String lower = type.toLowerCase();
0190:                if (lower.equals("to")) {
0191:                    return to;
0192:                } else if (lower.equals("cc")) {
0193:                    return cc;
0194:                } else if (lower.equals("bcc")) {
0195:                    return bcc;
0196:                }
0197:                throw new IllegalArgumentException(
0198:                        "Address type is not 'to', 'cc', or 'bcc'");
0199:            }
0200:
0201:            /**
0202:             * Checks if the string is a valid MMS address according to the grammar
0203:             * in Appendix D of the spec.
0204:             * @param addr the address to check
0205:             * @return MMSAddress representing the valid address, otherwise null.
0206:             */
0207:            MMSAddress checkValidAddress(String addr)
0208:                    throws IllegalArgumentException {
0209:                MMSAddress parsedAddress = MMSAddress.getParsedMMSAddress(addr);
0210:                // check to make sure there's a device address
0211:                if (parsedAddress == null
0212:                        || parsedAddress.type == MMSAddress.INVALID_ADDRESS
0213:                        || parsedAddress.type == MMSAddress.APP_ID) {
0214:                    throw new IllegalArgumentException(
0215:                            "Invalid destination address: " + addr);
0216:                }
0217:                return parsedAddress;
0218:            }
0219:
0220:            /**
0221:             * Checks an application ID to see if it can be legally added to this
0222:             * message. The spec requires that only a single applicationID can be
0223:             * specified for any <code>MultipartMessage</code>.
0224:             * @param newAppID the candidate applicationID to check. May be 
0225:             *      <code>null</code>
0226:             * @throws IllegalArgumentException if newAppID conflicts with an
0227:             *      applicationID already specified for this message.
0228:             */
0229:            void checkApplicationID(String newAppID)
0230:                    throws IllegalArgumentException {
0231:                if (applicationID != null) {
0232:                    if (!applicationID.equals(newAppID)) {
0233:                        throw new IllegalArgumentException(
0234:                                "Only one Application-ID can be specified per message");
0235:                    }
0236:                } else {
0237:                    applicationID = newAppID;
0238:                }
0239:            }
0240:
0241:            /** Array of allowed MMS header fields. */
0242:            static final String[] ALLOWED_HEADER_FIELDS = {
0243:                    "X-Mms-Delivery-Time", "X-Mms-Priority" };
0244:
0245:            /** Array of default header values. */
0246:            static final String[] DEFAULT_HEADER_VALUES = { null, "Normal" };
0247:
0248:            /** Array of known header fields. */
0249:            static final String[] KNOWN_HEADER_FIELDS = {
0250:                    // mandatory fields
0251:                    "X-Mms-Message-Type", "X-Mms-Transaction-ID",
0252:                    "X-Mms-MMS-Version", "X-Mms-Content-Type",
0253:                    // optional fields supported by this implementation
0254:                    "X-Mms-Subject", "X-Mms-From", "X-Mms-To", "X-Mms-CC",
0255:                    "X-Mms-BCC" };
0256:
0257:            /**
0258:             * Checks if header field is known.
0259:             *
0260:             * @param headerField the header field key to check
0261:             * @return <code>true</code> if the header is known
0262:             */
0263:            static boolean isKnownHeaderField(String headerField) {
0264:                String lowerFieldName = headerField.toLowerCase();
0265:                for (int i = 0; i < KNOWN_HEADER_FIELDS.length; ++i) {
0266:                    if (lowerFieldName.equals(KNOWN_HEADER_FIELDS[i]
0267:                            .toLowerCase())) {
0268:                        return true;
0269:                    }
0270:                }
0271:                return false;
0272:            }
0273:
0274:            /**
0275:             * Sets default values for all allowed header fields.
0276:             */
0277:            void setupHeaderFields() {
0278:                headerValues = new String[ALLOWED_HEADER_FIELDS.length];
0279:                for (int i = 0; i < DEFAULT_HEADER_VALUES.length; ++i) {
0280:                    headerValues[i] = DEFAULT_HEADER_VALUES[i];
0281:                }
0282:            }
0283:
0284:            /**
0285:             * Gets the location of the requested header from the
0286:             * list of allowed header fields.
0287:             *
0288:             * @param headerField the header field key to be checked
0289:             * @return the index of the requested header field, or 
0290:             * -1 if the header is not supported
0291:             */
0292:            static int getHeaderFieldIndex(String headerField) {
0293:                String lowerFieldName = headerField.toLowerCase();
0294:                for (int i = 0; i < ALLOWED_HEADER_FIELDS.length; ++i) {
0295:                    if (lowerFieldName.equals(ALLOWED_HEADER_FIELDS[i]
0296:                            .toLowerCase())) {
0297:                        return i;
0298:                    }
0299:                }
0300:                return -1;
0301:            }
0302:
0303:            /**
0304:             * Checks if allowed to access the requested header field.
0305:             *
0306:             * @param field the header field key to check
0307:             * @return <code>true</code> if the header exists
0308:             */
0309:            boolean isAllowedToAccessHeaderField(String field) {
0310:                return (getHeaderFieldIndex(field) != -1);
0311:            }
0312:
0313:            /**
0314:             * Checks the header field value.
0315:             * @param headerIndex the index of the header field to check
0316:             * @param value the value to be checked
0317:             * @exception Error if an invalid header index is requested
0318:             * @exception IllegalArgumentException if the value is not
0319:             * a valid delivery time or priority
0320:             */
0321:            static void checkHeaderValue(int headerIndex, String value) {
0322:                switch (headerIndex) {
0323:                case 0: // X-Mms-Delivery-Time
0324:                    try {
0325:                        Long.parseLong(value);
0326:                        return;
0327:                    } catch (NumberFormatException nfe) {
0328:                        // do nothing... we'll report the error in a second
0329:                    }
0330:                    break;
0331:                case 1: // X-Mms-Priority
0332:                {
0333:                    String lower = value.toLowerCase();
0334:                    if (lower.equals("normal") || lower.equals("high")
0335:                            || lower.equals("low")) {
0336:                        return;
0337:                    }
0338:                    // we'll report the error in a second
0339:                    break;
0340:                }
0341:                default:
0342:                    throw new Error("Unknown headerIndex: " + headerIndex);
0343:                }
0344:                // report the error
0345:                throw new IllegalArgumentException("Illegal value for header "
0346:                        + ALLOWED_HEADER_FIELDS[headerIndex] + ": " + value);
0347:            }
0348:
0349:            /**
0350:             * Adds an address to the multipart message.
0351:             * @param type the address type ("to", "cc" or "bcc") as a 
0352:             *      <code>String</code>. Each message can have none or multiple "to",
0353:             *      "cc" and "bcc" addresses. Each address is added separately. The
0354:             *      type is not case-sensitive.
0355:             * @param address the address as a <code>String</code>
0356:             * @return <code>true</code> if it was possible to add the address, else
0357:             *      <code>false</code>
0358:             * @exception java.lang.IllegalArgumentException if type is none of 
0359:             *      "to", "cc", or "bcc" or if <code>address</code> is not valid.
0360:             * @see #setAddress(String)
0361:             */
0362:            public boolean addAddress(java.lang.String type,
0363:                    java.lang.String address) throws IllegalArgumentException {
0364:
0365:                MMSAddress parsedAddress = checkValidAddress(address);
0366:                String appID = parsedAddress.appId;
0367:                if (appID != null) {
0368:                    checkApplicationID(appID);
0369:                }
0370:
0371:                Vector which = getAddressList(type);
0372:                if (!which.contains(address)) {
0373:                    which.addElement(address);
0374:                    return true;
0375:                }
0376:                return false;
0377:            }
0378:
0379:            /**
0380:             * Maximum size of MMS message.
0381:             * Default value is 30730 (30K)
0382:             */
0383:            static final int MAX_TOTAL_SIZE = 30730;
0384:
0385:            /**
0386:             * Attaches a <code>MessagePart</code> to the multipart message.
0387:             * @param part <code>MessagePart</code> to add
0388:             * @exception java.lang.IllegalArgumentException if the Content-ID of the
0389:             *      <code>MessagePart</code> conflicts with a Content-ID of a
0390:             *      <code>MessagePart</code> already contained in this 
0391:             *      <code>MultiPartMessage</code>. The Content-IDs must be unique
0392:             *      within a MultipartMessage.
0393:             * @exception NullPointerException if the parameter is <code>null</code>
0394:             * @exception SizeExceededException if it's not possible to attach the 
0395:             *      <code>MessagePart</code>.
0396:             */
0397:            public void addMessagePart(MessagePart part)
0398:                    throws SizeExceededException {
0399:                String this ContentID = part.getContentID();
0400:                boolean duplicateContentID = false;
0401:                int totalSizeSoFar = 0;
0402:                int numPartsSoFar = parts.size();
0403:                for (int i = 0; i < numPartsSoFar; ++i) {
0404:                    MessagePart onePart = (MessagePart) parts.elementAt(i);
0405:                    if (this ContentID.equals(onePart.getContentID())) {
0406:                        throw new IllegalArgumentException(
0407:                                "Cannot add duplicate content-id: "
0408:                                        + this ContentID);
0409:                    }
0410:                    totalSizeSoFar += onePart.getLength();
0411:                }
0412:                if (totalSizeSoFar + part.getLength() > MAX_TOTAL_SIZE) {
0413:                    throw new SizeExceededException(
0414:                            "Adding this MessagePart would exceed max size of "
0415:                                    + MAX_TOTAL_SIZE + " bytes");
0416:                }
0417:                parts.addElement(part);
0418:            }
0419:
0420:            /**
0421:             * Returns the "from" address associated with this message, e.g. address of
0422:             * the sender. If the message is a newly created message, e.g. not a 
0423:             * received one, then the first "to" address is returned.
0424:             * Returns <code>null</code> if the "from" or "to" address for the
0425:             * message, dependent on the case, are not set.
0426:             * Note: This design allows sending responses to a received message easily 
0427:             * by reusing the same <code>Message</code> object and just replacing the
0428:             * payload. The address field can normally be kept untouched (unless the
0429:             * used messaging protocol requires some special handling of the address).
0430:             * @return the "from" or "to" address of this message, or <code>null</code>
0431:             *      if the address that is expected as a result of this method is not
0432:             *      set
0433:             * @see #setAddress(String)
0434:             */
0435:            public java.lang.String getAddress() {
0436:                String returnMe = null;
0437:                Date tStamp = getTimestamp();
0438:                if (tStamp == null || tStamp.getTime() == 0L) {
0439:                    // not a received message - use the first "to" address
0440:                    if (to.size() > 0) {
0441:                        returnMe = (String) to.elementAt(0);
0442:                    }
0443:                } else {
0444:                    // received - use the "from" address
0445:                    returnMe = super .getAddress();
0446:                }
0447:                return returnMe;
0448:            }
0449:
0450:            /**
0451:             * Gets the addresses of the multipart message of the specified type (e.g.
0452:             * "to", "cc", "bcc" or "from") as <code>String</code>. The method is not
0453:             * case sensitive.
0454:             * @param type the type of addresses to return
0455:             * @return the addresses as a <code>String</code> array or <code>null</code>
0456:             *      if this value is not present.
0457:             */
0458:            public java.lang.String[] getAddresses(java.lang.String type) {
0459:                if (type.toLowerCase().equals("from")) {
0460:                    String address = super .getAddress();
0461:                    if (address == null) {
0462:                        return null;
0463:                    }
0464:                    return new String[] { address };
0465:                }
0466:                Vector which = getAddressList(type);
0467:                int num = which.size();
0468:                if (num == 0) {
0469:                    return null;
0470:                }
0471:                String[] addresses = new String[num];
0472:                which.copyInto(addresses);
0473:                return addresses;
0474:            }
0475:
0476:            /**
0477:             * Gets the content of the specific header field of the multipart message.
0478:             * @param headerField the name of the header field as a <code>String</code>
0479:             * @return the content of the specified header field as a 
0480:             *      <code>String</code> or <code>null</code> of the specified header
0481:             *      field is not present.
0482:             * @exception SecurityException if the access to specified header field is 
0483:             *      restricted
0484:             * @exception IllegalArgumentException if <code>headerField</code> 
0485:             *      is unknown
0486:             * @see Appendix D for known headerFields
0487:             * @see #setHeader
0488:             */
0489:            public java.lang.String getHeader(java.lang.String headerField) {
0490:                if (headerField == null) {
0491:                    throw new IllegalArgumentException(
0492:                            "headerField must not be null");
0493:                }
0494:                if (isAllowedToAccessHeaderField(headerField)) {
0495:                    int index = getHeaderFieldIndex(headerField);
0496:                    if (index != -1) {
0497:                        return headerValues[index];
0498:                    }
0499:                    throw new Error(
0500:                            "Allowed to access field but it has no index");
0501:                }
0502:                if (isKnownHeaderField(headerField)) {
0503:                    throw new SecurityException(
0504:                            "Cannot access restricted header field: "
0505:                                    + headerField);
0506:                } else {
0507:                    throw new IllegalArgumentException("Unknown header field: "
0508:                            + headerField);
0509:                }
0510:            }
0511:
0512:            /**
0513:             * This method returns a <code>MessagePart</code> from the message that
0514:             * matches the content-id passed as a parameter.
0515:             * @param contentID the content-id for the <code>MessagePart</code> to be
0516:             *      returned
0517:             * @return <code>MessagePart</code> that matches the provided content-id or
0518:             *      <code>null</code> if there is no <code>MessagePart</code> in this
0519:             *      message with the provided content-id
0520:             * @exception NullPointerException if the parameter is <code>null</code>
0521:             */
0522:            public MessagePart getMessagePart(java.lang.String contentID) {
0523:                if (contentID == null) {
0524:                    throw new NullPointerException("contentID must not be null");
0525:                }
0526:                int numParts = parts.size();
0527:                for (int i = 0; i < numParts; ++i) {
0528:                    MessagePart onePart = (MessagePart) parts.elementAt(i);
0529:                    if (contentID.equals(onePart.getContentID())) {
0530:                        return onePart;
0531:                    }
0532:                }
0533:                return null;
0534:            }
0535:
0536:            /**
0537:             * Returns an array of all <code>MessagePart</code>s of this message.
0538:             * @return array of <code>MessagePart</code>s, or <code>null</code> if no
0539:             *      <code>MessagePart</code>s are available
0540:             */
0541:            public MessagePart[] getMessageParts() {
0542:                int num = parts.size();
0543:                if (num == 0) {
0544:                    return null;
0545:                }
0546:                MessagePart[] msgParts = new MessagePart[num];
0547:                parts.copyInto(msgParts);
0548:                return msgParts;
0549:            }
0550:
0551:            /**
0552:             * Returns the <code>contentId</code> of the start <code>MessagePart</code>.
0553:             * The start <code>MessagePart</code> is set in 
0554:             * <code>setStartContentId(String)</code>
0555:             * @return the content-id of the start <code>MessagePart</code> or
0556:             *      <code>null</code> if the start <code>MessagePart</code> is not set.
0557:             * @see #setStartContentId(String)
0558:             */
0559:            public java.lang.String getStartContentId() {
0560:                return startContentID;
0561:            }
0562:
0563:            /**
0564:             * Gets the subject of the multipart message.
0565:             * @return the message subject as a <code>String</code> or <code>null</code>
0566:             *      if this value is not present.
0567:             * @see #setSubject
0568:             */
0569:            public java.lang.String getSubject() {
0570:                return subject;
0571:            }
0572:
0573:            /**
0574:             * Cleans application Id value.
0575:             */
0576:            private void cleanupAppID() throws IllegalStateException {
0577:                Vector addresses = to;
0578:                boolean checkedTo = false;
0579:                boolean checkedCC = false;
0580:                int currIndex = 0;
0581:                boolean matchedAppID = false;
0582:                while (true) {
0583:                    if (currIndex >= addresses.size()) {
0584:                        if (!checkedTo) {
0585:                            checkedTo = true;
0586:                            addresses = cc;
0587:                            currIndex = 0;
0588:                            continue;
0589:                        } else if (!checkedCC) {
0590:                            checkedCC = true;
0591:                            addresses = bcc;
0592:                            currIndex = 0;
0593:                            continue;
0594:                        } else {
0595:                            break;
0596:                        }
0597:
0598:                    }
0599:                    String addr = (String) addresses.elementAt(currIndex++);
0600:                    MMSAddress parsedAddress = MMSAddress
0601:                            .getParsedMMSAddress(addr);
0602:                    if (parsedAddress == null
0603:                            || parsedAddress.type == MMSAddress.INVALID_ADDRESS
0604:                            || parsedAddress.type == MMSAddress.APP_ID) {
0605:                        throw new IllegalStateException("Invalid MMS address: "
0606:                                + addr);
0607:                    }
0608:                    String this AppID = parsedAddress.appId;
0609:                    if (this AppID != null && this AppID.equals(applicationID)) {
0610:                        matchedAppID = true;
0611:                    }
0612:                }
0613:                if (!matchedAppID) {
0614:                    applicationID = null;
0615:                }
0616:            }
0617:
0618:            /**
0619:             * Removes an address from the multipart message.
0620:             * @param type the address type ("to", "cc", or "bcc") as a
0621:             *      <code>String</code>
0622:             * @param address the address as a <code>String</code>
0623:             * @return <code>true</code> if it was possible to delete the address, else
0624:             *      <code>false</code>
0625:             * @throws NullPointerException is type is <code>null</code>
0626:             * @throws java.lang.IllegalArgumentException if type is none of "to", "cc",
0627:             *      or "bcc"
0628:             */
0629:            public boolean removeAddress(java.lang.String type,
0630:                    java.lang.String address) {
0631:                Vector which = getAddressList(type);
0632:                boolean result = which.removeElement(address);
0633:                cleanupAppID();
0634:                return result;
0635:            }
0636:
0637:            /**
0638:             * Removes all addresses of types "to", "cc", "bcc" from the
0639:             * multipart message.
0640:             * @see #setAddress(String)
0641:             * @see #addAddress(String, String)
0642:             */
0643:            public void removeAddresses() {
0644:                to.removeAllElements();
0645:                cc.removeAllElements();
0646:                bcc.removeAllElements();
0647:                applicationID = null;
0648:            }
0649:
0650:            /**
0651:             * Removes all addresses of the specified type from the multipart message.
0652:             * @param type the address type ("to", "cc", or "bcc") as a 
0653:             *      <code>String</code>
0654:             * @throws NullPointerException if type is <code>null</code>
0655:             * @throws java.lang.IllegalArgumentException if type is none of "to", "cc",
0656:             *      or "bcc"
0657:             */
0658:            public void removeAddresses(java.lang.String type) {
0659:                Vector which = getAddressList(type);
0660:                which.removeAllElements();
0661:                cleanupAppID();
0662:            }
0663:
0664:            /**
0665:             * Removes a <code>MessagePart</code> from the multipart message.
0666:             * @param part <code>MessagePart</code> to delete
0667:             * @return <code>true</code> if it was possible to remove the
0668:             *      <code>MessagePart</code>, else <code>false</code>
0669:             * @exception NullPointerException id the parameter is <code>null</code>
0670:             */
0671:            public boolean removeMessagePart(MessagePart part) {
0672:                if (part == null) {
0673:                    throw new NullPointerException("part must not be null");
0674:                }
0675:                if (part.getContentID().equals(startContentID)) {
0676:                    startContentID = null;
0677:                }
0678:                return parts.removeElement(part);
0679:            }
0680:
0681:            /**
0682:             * Removes a <code>MessagePart</code> with the specific 
0683:             * <code>contentID</code> from the multipart message.
0684:             * @param contentID identifies which <code>MessagePart</code> must be
0685:             *      deleted.
0686:             * @return <code>true</code> if it was possible to remove the
0687:             *      <code>MessagePart</code>, else <code>false</code>
0688:             * @exception NullPointerException if the parameter is <code>null</code>
0689:             */
0690:            public boolean removeMessagePartId(java.lang.String contentID) {
0691:                if (contentID == null) {
0692:                    throw new NullPointerException("contentID must not be null");
0693:                }
0694:                int numParts = parts.size();
0695:                for (int i = 0; i < numParts; ++i) {
0696:                    MessagePart onePart = (MessagePart) parts.elementAt(i);
0697:                    if (contentID.equals(onePart.getContentID())) {
0698:                        if (contentID.equals(startContentID)) {
0699:                            startContentID = null;
0700:                        }
0701:                        parts.removeElementAt(i);
0702:                        return true;
0703:                    }
0704:                }
0705:                return false;
0706:            }
0707:
0708:            /**
0709:             * Removes <code>MessagePart</code>s with the specific content location
0710:             * from the multipart message. All <code>MessagePart</code>s with the
0711:             * specified <code>contentLocation</code> are removed.
0712:             * @param contentLocation content location (file name) of the 
0713:             *      <code>MessagePart</code>
0714:             * @return <code>true</code> if it was possible to remove the
0715:             *      <code>MessagePart</code>, else <code>false</code>
0716:             * @exception NullPointerException if the parameter is <code>null</code>
0717:             */
0718:            public boolean removeMessagePartLocation(
0719:                    java.lang.String contentLocation) {
0720:                if (contentLocation == null) {
0721:                    throw new NullPointerException(
0722:                            "contentLocation must not be null");
0723:                }
0724:                int numParts = parts.size();
0725:                boolean found = false;
0726:                for (int i = 0; i < numParts; ++i) {
0727:                    MessagePart onePart = (MessagePart) parts.elementAt(i);
0728:                    if (contentLocation.equals(onePart.getContentLocation())) {
0729:                        if (onePart.getContentID().equals(startContentID)) {
0730:                            startContentID = null;
0731:                        }
0732:                        parts.removeElementAt(i);
0733:                        --numParts;
0734:                        --i;
0735:                        found = true;
0736:                    }
0737:                }
0738:                return found;
0739:            }
0740:
0741:            /**
0742:             * Sets the "to" address associated with this message. It works the same way
0743:             * as <code>addAddress("to", addr)</code>. The address may be set to
0744:             * <code>null</code>.
0745:             * @param address address for the message
0746:             * @see #getAddress()
0747:             * @see #addAddress(String, String)
0748:             */
0749:            public void setAddress(java.lang.String address) {
0750:                if (address != null) {
0751:                    addAddress("to", address);
0752:                }
0753:                // otherwise it's a no-op.
0754:            }
0755:
0756:            /**
0757:             * Sets the specified header of the multipart message. The header value can
0758:             * be <code>null</code>.
0759:             * @param headerField the name of the header field as a <code>String</code>
0760:             * @param headerValue the value of the header as a <code>String</code>
0761:             * @exception java.lang.IllegalArgumentException if 
0762:             *      <code>headerField</code> is unknown, or if 
0763:             *      <code>headerValue</code> is not correct (depends on
0764:             *      <code>headerField</code>!)
0765:             * @exception NullPointerException if <code>headerField</code> is 
0766:             *      <code>null</code>
0767:             * @exception SecurityException if the access to specified header field is
0768:             *      restricted
0769:             * @see #getHeader(String)
0770:             * @see Appendix D
0771:             */
0772:            public void setHeader(java.lang.String headerField,
0773:                    java.lang.String headerValue) {
0774:                if (isAllowedToAccessHeaderField(headerField)) {
0775:                    int index = getHeaderFieldIndex(headerField);
0776:                    if (index != -1) {
0777:                        if (headerValue != null) {
0778:                            checkHeaderValue(index, headerValue);
0779:                        }
0780:                        headerValues[index] = headerValue;
0781:                        return;
0782:                    }
0783:                    throw new Error(
0784:                            "Allowed to access field but it has no index");
0785:                }
0786:                if (isKnownHeaderField(headerField)) {
0787:                    throw new SecurityException(
0788:                            "Cannot access restricted header field: "
0789:                                    + headerField);
0790:                } else {
0791:                    throw new IllegalArgumentException("Unknown header field: "
0792:                            + headerField);
0793:                }
0794:            }
0795:
0796:            /**
0797:             * Sets the <code>Content-ID</code> of the start <code>MessagePart</code> of
0798:             * a multipart related message. The <code>Content-ID</code> may be set to
0799:             * <code>null</code>. The <code>StartContentId</code> is set for the
0800:             * MessagePart that is used to reference the other MessageParts of the
0801:             * MultipartMessage for presentation or processing purposes.
0802:             * @param contentId as a <code>String</code>
0803:             * @exception java.lang.IllegalArgumentException if 
0804:             *      <code>contentId</code> is none of the added 
0805:             *      <code>MessagePart</code> objects matches the
0806:             *      <code>contentId</code>
0807:             * @see #getStartContentId()
0808:             */
0809:            public void setStartContentId(java.lang.String contentId) {
0810:                if (contentId != null) {
0811:                    if (getMessagePart(contentId) == null) {
0812:                        throw new IllegalArgumentException(
0813:                                "Unknown contentId: " + contentId);
0814:                    }
0815:                }
0816:                startContentID = contentId;
0817:            }
0818:
0819:            /**
0820:             * Sets the Subject of the multipart message. This value can be
0821:             * <code>null</code>.
0822:             * @param subject the message subject as a <code>String</code>
0823:             * @see #getSubject()
0824:             */
0825:            public void setSubject(java.lang.String subject) {
0826:                if (subject != null && subject.length() > 40) { // MMS Conformance limit
0827:                    throw new IllegalArgumentException(
0828:                            "Subject exceeds 40 chars");
0829:                }
0830:                this .subject = subject;
0831:            }
0832:
0833:            /**
0834:             * Returns only the device part of the MMS Address.
0835:             * @return the device portion of the MMS Address
0836:             * @param address the MMS address
0837:             * @throws IllegalArgumentException if the MMS Address has no
0838:             *  device portion.
0839:             */
0840:            static String getDevicePortionOfAddress(String address)
0841:                    throws IllegalArgumentException {
0842:                MMSAddress parsedAddress = MMSAddress
0843:                        .getParsedMMSAddress(address);
0844:                if (parsedAddress == null || parsedAddress.address == null) {
0845:                    throw new IllegalArgumentException("MMS Address "
0846:                            + "has no device portion");
0847:                }
0848:                return parsedAddress.address;
0849:            }
0850:
0851:            /**
0852:             * Writes a vector to an output stream. If the contents are MMS addresses,
0853:             * as indicated by the <code>isAddress</code> parameter, then
0854:             * only the device
0855:             * part of the address is placed into the vector, not the
0856:             * application-id, if any.
0857:             * @param dos the data output stream for writing
0858:             * @param v the array to be written
0859:             * @param isAddress is the contents of the vector an MMS address.
0860:             * @exception IOException if any I/O errors occur
0861:             */
0862:            static void writeVector(DataOutputStream dos, Vector v,
0863:                    boolean isAddress) throws IOException {
0864:                StringBuffer buff = new StringBuffer();
0865:                int len = v.size();
0866:                String appendMe = null;
0867:                if (len > 0) {
0868:                    appendMe = (String) v.elementAt(0);
0869:                    if (isAddress) {
0870:                        appendMe = getDevicePortionOfAddress(appendMe);
0871:                    }
0872:                    buff.append(appendMe);
0873:                }
0874:                for (int i = 1; i < len; ++i) {
0875:                    buff.append("; ");
0876:                    appendMe = (String) v.elementAt(i);
0877:                    if (isAddress) {
0878:                        appendMe = getDevicePortionOfAddress(appendMe);
0879:                    }
0880:                    buff.append(appendMe);
0881:                }
0882:                dos.writeUTF(buff.toString());
0883:            }
0884:
0885:            /**
0886:             * Reads a vector from an input stream. If the content is an MMS Address,
0887:             * as indicated by the <code>isAddress</code> parameter, then the prefix
0888:             * <code>"mms://"</code> is added to each address.
0889:             * @param dis the data input stream for reading
0890:             * @param v the array to be returned
0891:             * @param isAddress the contents are MMS Addresses
0892:             * @exception IOException if any I/O errors occur
0893:             */
0894:            static void readVector(DataInputStream dis, Vector v,
0895:                    boolean isAddress) throws IOException {
0896:                String inputStr = dis.readUTF();
0897:                int prevDelim = -2;
0898:                String prefix = "";
0899:                if (isAddress) {
0900:                    prefix = "mms://";
0901:                }
0902:                while (prevDelim != -1) {
0903:                    int nextDelim = inputStr.indexOf("; ", prevDelim + 2);
0904:                    String addStr = null;
0905:                    if (nextDelim == -1) {
0906:                        addStr = prefix + inputStr.substring(prevDelim + 2);
0907:                    } else {
0908:                        addStr = prefix
0909:                                + inputStr.substring(prevDelim + 2, nextDelim);
0910:                    }
0911:                    v.addElement(addStr);
0912:                    prevDelim = nextDelim;
0913:                }
0914:            }
0915:
0916:            /**
0917:             * Writes a message part to the output stream
0918:             * @param dos the data output stream for writing
0919:             * @param p the message part to be written
0920:             * @exception IOException if any I/O errors occur
0921:             */
0922:            static void writeMessagePart(DataOutputStream dos, MessagePart p)
0923:                    throws IOException {
0924:                dos.writeUTF("Content-Type");
0925:                StringBuffer contentType = new StringBuffer(p.getMIMEType());
0926:                String loc = p.getContentLocation();
0927:                if (loc != null) {
0928:                    contentType.append("; name=\"");
0929:                    contentType.append(loc);
0930:                    contentType.append("\"");
0931:                }
0932:                dos.writeUTF(contentType.toString());
0933:                String id = p.getContentID();
0934:                if (id != null) {
0935:                    dos.writeUTF("Content-ID");
0936:                    dos.writeUTF(id);
0937:                }
0938:                String enc = p.getEncoding();
0939:                if (enc != null) {
0940:                    dos.writeUTF("Encoding");
0941:                    dos.writeUTF(enc);
0942:                }
0943:                // the payload
0944:                dos.writeUTF("Content-Length");
0945:                dos.writeInt(p.getLength());
0946:                dos.writeUTF("Content");
0947:                dos.write(p.getContent());
0948:            }
0949:
0950:            /**
0951:             * Create a new message part from the input stream
0952:             * @param dis the data input stream for reading
0953:             * @exception IOException if any I/O errors occur
0954:             * @return the message object instance
0955:             */
0956:            static MessagePart createMessagePart(DataInputStream dis)
0957:                    throws IOException {
0958:                String nextField = dis.readUTF(); // eats "Content-Type" header
0959:                String contentType = dis.readUTF();
0960:                nextField = dis.readUTF();
0961:                String contentID = null;
0962:                if (nextField.equals("Content-ID")) {
0963:                    contentID = dis.readUTF();
0964:                    nextField = dis.readUTF();
0965:                }
0966:                String encoding = null;
0967:                if (nextField.equals("Encoding")) {
0968:                    encoding = dis.readUTF();
0969:                    nextField = dis.readUTF();
0970:                }
0971:                // "Content-Length" was just eaten
0972:                int length = dis.readInt();
0973:                byte[] contents = new byte[length];
0974:                nextField = dis.readUTF(); // eats the "Content" header
0975:                dis.readFully(contents);
0976:                // now separate the content location and mime type
0977:                String mimeType = contentType;
0978:                String contentLocation = null;
0979:                int sepPos = contentType.indexOf(';');
0980:                if (sepPos != -1
0981:                        && contentType.substring(sepPos)
0982:                                .startsWith("; name=\"")) {
0983:                    contentLocation = contentType.substring(sepPos + 8, // ; name="
0984:                            contentType.length() - 1);
0985:                    mimeType = contentType.substring(0, sepPos);
0986:                }
0987:                return new MessagePart(contents, mimeType, contentID,
0988:                        contentLocation, encoding);
0989:            }
0990:
0991:            /** The content type for the MMS message. */
0992:            static final String STREAM_SIGNATURE = "application/vnd.wap.mms-message";
0993:
0994:            /**
0995:             * Gets the message object as a byte array.
0996:             *
0997:             * @exception IOException if any I/O errors occur
0998:             * @return the serialized byte array of the message object
0999:             */
1000:            public byte[] getAsByteArray() throws IOException {
1001:
1002:                ByteArrayOutputStream baos = new ByteArrayOutputStream();
1003:                DataOutputStream dos = new DataOutputStream(baos);
1004:
1005:                dos.writeUTF(STREAM_SIGNATURE);
1006:
1007:                dos.writeUTF("X-Mms-Message-Type");
1008:                dos.writeUTF("m-send-req");
1009:                dos.writeUTF("X-Mms-Transaction-ID");
1010:                dos.writeUTF(String.valueOf(System.currentTimeMillis()));
1011:                dos.writeUTF("X-Mms-Version");
1012:                dos.writeUTF("1.0");
1013:                for (int i = 0; i < ALLOWED_HEADER_FIELDS.length; ++i) {
1014:                    String headerValue = headerValues[i];
1015:                    if (headerValue != null) {
1016:                        dos.writeUTF(ALLOWED_HEADER_FIELDS[i]);
1017:                        dos.writeUTF(headerValue);
1018:                    }
1019:                }
1020:                String fromAddress = super .getAddress();
1021:                if (fromAddress != null) {
1022:                    dos.writeUTF("From");
1023:                    dos.writeUTF(getDevicePortionOfAddress(fromAddress));
1024:                }
1025:                if (to.size() != 0) {
1026:                    dos.writeUTF("To");
1027:                    writeVector(dos, to, true);
1028:                }
1029:                if (cc.size() != 0) {
1030:                    dos.writeUTF("Cc");
1031:                    writeVector(dos, cc, true);
1032:                }
1033:                if (bcc.size() != 0) {
1034:                    dos.writeUTF("Bcc");
1035:                    writeVector(dos, bcc, true);
1036:                }
1037:                long date = 0L;
1038:                Date tStamp = getTimestamp();
1039:                if (tStamp != null && (date = tStamp.getTime()) != 0L) {
1040:                    dos.writeUTF("Date");
1041:                    dos.writeUTF(String.valueOf(date));
1042:                }
1043:                if (subject != null) {
1044:                    dos.writeUTF("Subject");
1045:                    dos.writeUTF(subject);
1046:                }
1047:                dos.writeUTF("Content-Type");
1048:                Vector contentTypeElements = new Vector();
1049:                if (startContentID != null) {
1050:                    contentTypeElements
1051:                            .addElement("application/vnd.wap.multipart.related");
1052:                } else {
1053:                    contentTypeElements
1054:                            .addElement("application/vnd.wap.multipart.mixed");
1055:                }
1056:                if (startContentID != null) {
1057:                    contentTypeElements.addElement("start = <" + startContentID
1058:                            + ">");
1059:                    contentTypeElements.addElement("type = "
1060:                            + getMessagePart(startContentID).getMIMEType());
1061:                }
1062:                if (applicationID != null) {
1063:                    contentTypeElements.addElement("Application-ID = "
1064:                            + applicationID);
1065:                }
1066:                if (replyToApplicationID != null) {
1067:                    contentTypeElements.addElement("Reply-To-Application-ID = "
1068:                            + replyToApplicationID);
1069:                }
1070:                writeVector(dos, contentTypeElements, false);
1071:                dos.writeUTF("nEntries");
1072:                int numParts = parts.size();
1073:                dos.writeUTF(String.valueOf(numParts));
1074:                for (int i = 0; i < numParts; ++i) {
1075:                    MessagePart p = (MessagePart) parts.elementAt(i);
1076:                    writeMessagePart(dos, p);
1077:                }
1078:                dos.close();
1079:                byte[] returnMe = baos.toByteArray();
1080:                baos.close();
1081:                return returnMe;
1082:            }
1083:
1084:            /**
1085:             * Create a message object from a serialized byte array.
1086:             *
1087:             * @param data a serialized byte array of a message object
1088:             * @return the multipart message object
1089:             * @exception IOException if any I/O errors occur
1090:             */
1091:            public static MultipartObject createFromByteArray(byte[] data)
1092:                    throws IOException {
1093:
1094:                ByteArrayInputStream bais = new ByteArrayInputStream(data);
1095:                DataInputStream dis = new DataInputStream(bais);
1096:
1097:                String signature = dis.readUTF();
1098:                if (!signature.equals(STREAM_SIGNATURE)) {
1099:                    throw new IOException("invalid data format");
1100:                }
1101:                // eat the first 6 entries: "X-Mms-Message-Type", "m-send-req", 
1102:                // "X-Mms-Transaction-ID", <transactionID>, "X-Mms-Version", "1.0"
1103:                for (int i = 0; i < 6; ++i) {
1104:                    dis.readUTF();
1105:                }
1106:
1107:                String[] headerValues = new String[ALLOWED_HEADER_FIELDS.length];
1108:                String nextField = dis.readUTF();
1109:                int headerIndex;
1110:                while ((headerIndex = getHeaderFieldIndex(nextField)) != -1) {
1111:                    headerValues[headerIndex] = dis.readUTF();
1112:                    nextField = dis.readUTF();
1113:                }
1114:                String fromAddress = null;
1115:                if (nextField.equals("From")) {
1116:                    fromAddress = "mms://" + dis.readUTF();
1117:                    nextField = dis.readUTF();
1118:                }
1119:                Vector to = new Vector();
1120:                if (nextField.equals("To")) {
1121:                    readVector(dis, to, true);
1122:                    nextField = dis.readUTF();
1123:                }
1124:                Vector cc = new Vector();
1125:                if (nextField.equals("Cc")) {
1126:                    readVector(dis, cc, true);
1127:                    nextField = dis.readUTF();
1128:                }
1129:                Vector bcc = new Vector();
1130:                if (nextField.equals("Bcc")) {
1131:                    readVector(dis, bcc, true);
1132:                    nextField = dis.readUTF();
1133:                }
1134:                long date = 0L;
1135:                if (nextField.equals("Date")) {
1136:                    String dateStr = dis.readUTF();
1137:                    try {
1138:                        date = Long.parseLong(dateStr);
1139:                    } catch (NumberFormatException nfe) {
1140:                        date = 0L;
1141:                    }
1142:                    nextField = dis.readUTF();
1143:                }
1144:                String subject = null;
1145:                if (nextField.equals("Subject")) {
1146:                    subject = dis.readUTF();
1147:                    nextField = dis.readUTF();
1148:                }
1149:                // nextField is "Content-Type"
1150:                String startContentID = null;
1151:                String applicationID = null;
1152:                String replyToApplicationID = null;
1153:                Vector contentTypeElements = new Vector();
1154:                readVector(dis, contentTypeElements, false);
1155:                int numContentTypeElements = contentTypeElements.size();
1156:                for (int i = 0; i < numContentTypeElements; ++i) {
1157:                    String element = (String) contentTypeElements.elementAt(i);
1158:                    if (element.startsWith("start = <")) {
1159:                        startContentID = element.substring(9);
1160:                        startContentID = startContentID.substring(0,
1161:                                startContentID.length() - 1);
1162:                    } else if (element.startsWith("Application-ID = ")) {
1163:                        applicationID = element.substring(17);
1164:                    } else if (element.startsWith("Reply-To-Application-ID = ")) {
1165:                        replyToApplicationID = element.substring(26);
1166:                    }
1167:                }
1168:                nextField = dis.readUTF();
1169:                // nextField is "nEntries"
1170:                int numParts = 0;
1171:                String numPartsStr = dis.readUTF();
1172:                try {
1173:                    numParts = Integer.parseInt(numPartsStr);
1174:                } catch (NumberFormatException nfe) {
1175:                    numParts = 0;
1176:                }
1177:                Vector parts = new Vector();
1178:                for (int i = 0; i < numParts; ++i) {
1179:                    parts.addElement(createMessagePart(dis));
1180:                }
1181:                dis.close();
1182:                bais.close();
1183:
1184:                MultipartObject mpo = new MultipartObject(fromAddress);
1185:                mpo.setTimeStamp(date);
1186:                mpo.headerValues = headerValues;
1187:                mpo.subject = subject;
1188:                mpo.startContentID = startContentID;
1189:                mpo.to = to;
1190:                mpo.cc = cc;
1191:                /* 
1192:                 * Uncomment this if you want the "bcc"s to be visible to the recipients
1193:                mpo.bcc = bcc;
1194:                 */
1195:                mpo.parts = parts;
1196:                mpo.applicationID = applicationID;
1197:                mpo.replyToApplicationID = replyToApplicationID;
1198:                return mpo;
1199:            }
1200:
1201:            /**
1202:             * Gets the message object header as a byte array. The header is composed of
1203:             * a number of fields and is exclusive of the <code>MessagePart</code>
1204:             * contents.
1205:             *
1206:             * @throws IOException if any I/O errors occur.
1207:             * @return the serialized byte array of the message object
1208:             */
1209:            public byte[] getHeaderAsByteArray() throws IOException {
1210:
1211:                ByteArrayOutputStream baos = new ByteArrayOutputStream();
1212:                DataOutputStream dos = new DataOutputStream(baos);
1213:
1214:                dos.writeUTF(STREAM_SIGNATURE);
1215:
1216:                // Write headers that 
1217:                dos.writeUTF("X-Mms-Message-Type");
1218:                dos.writeUTF("m-send-req");
1219:                dos.writeUTF("X-Mms-Transaction-ID");
1220:                dos.writeUTF(String.valueOf(System.currentTimeMillis()));
1221:                dos.writeUTF("X-Mms-Version");
1222:                dos.writeUTF("1.0");
1223:
1224:                for (int i = 0; i < ALLOWED_HEADER_FIELDS.length; ++i) {
1225:                    String headerValue = headerValues[i];
1226:                    if (headerValue != null) {
1227:                        dos.writeUTF(ALLOWED_HEADER_FIELDS[i]);
1228:                        dos.writeUTF(headerValue);
1229:                    }
1230:                }
1231:                String fromAddress = super .getAddress();
1232:                if (fromAddress != null) {
1233:                    dos.writeUTF("From");
1234:                    dos.writeUTF(getDevicePortionOfAddress(fromAddress));
1235:                }
1236:                if (to.size() != 0) {
1237:                    dos.writeUTF("To");
1238:                    writeVector(dos, to, true);
1239:                }
1240:                if (cc.size() != 0) {
1241:                    dos.writeUTF("Cc");
1242:                    writeVector(dos, cc, true);
1243:                }
1244:                if (bcc.size() != 0) {
1245:                    dos.writeUTF("Bcc");
1246:                    writeVector(dos, bcc, true);
1247:                }
1248:                long date = 0L;
1249:                Date tStamp = getTimestamp();
1250:                if (tStamp != null && (date = tStamp.getTime()) != 0L) {
1251:                    dos.writeUTF("Date");
1252:                    dos.writeUTF(String.valueOf(date));
1253:                }
1254:                if (subject != null) {
1255:                    dos.writeUTF("Subject");
1256:                    dos.writeUTF(subject);
1257:                }
1258:                dos.writeUTF("Content-Type");
1259:                Vector contentTypeElements = new Vector();
1260:                if (startContentID != null) {
1261:                    contentTypeElements
1262:                            .addElement("application/vnd.wap.multipart.related");
1263:                } else {
1264:                    contentTypeElements
1265:                            .addElement("application/vnd.wap.multipart.mixed");
1266:                }
1267:                if (startContentID != null) {
1268:                    contentTypeElements.addElement("start = <" + startContentID
1269:                            + ">");
1270:                    contentTypeElements.addElement("type = "
1271:                            + getMessagePart(startContentID).getMIMEType());
1272:                }
1273:                if (applicationID != null) {
1274:                    contentTypeElements.addElement("Application-ID = "
1275:                            + applicationID);
1276:                }
1277:                if (replyToApplicationID != null) {
1278:                    contentTypeElements.addElement("Reply-To-Application-ID = "
1279:                            + replyToApplicationID);
1280:                }
1281:                writeVector(dos, contentTypeElements, false);
1282:                dos.close();
1283:                byte[] returnMe = baos.toByteArray();
1284:                baos.close();
1285:                return returnMe;
1286:            }
1287:
1288:            /**
1289:             * Gets the message object body as a byte array. The body is composed of a
1290:             * single header that states the number of entries, followed by a serialized
1291:             * array of <code>MessagePart</code> objects.
1292:             *
1293:             * @throws IOException if any I/O errors occur.
1294:             * @return the serialized byte array of the message body.
1295:             */
1296:            public byte[] getBodyAsByteArray() throws IOException {
1297:
1298:                ByteArrayOutputStream baos = new ByteArrayOutputStream();
1299:                DataOutputStream dos = new DataOutputStream(baos);
1300:
1301:                dos.writeUTF("nEntries");
1302:                int numParts = parts.size();
1303:                dos.writeUTF(String.valueOf(numParts));
1304:                for (int i = 0; i < numParts; ++i) {
1305:                    MessagePart p = (MessagePart) parts.elementAt(i);
1306:                    writeMessagePart(dos, p);
1307:                }
1308:
1309:                dos.close();
1310:                byte[] returnMe = baos.toByteArray();
1311:                baos.close();
1312:                return returnMe;
1313:            }
1314:
1315:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.