⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 emaildata.java

📁 moblie syncml mail javame
💻 JAVA
字号:
/*
 * Funambol is a mobile platform developed by Funambol, Inc. 
 * Copyright (C) 2003 - 2007 Funambol, Inc.
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission 
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE 
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Affero General Public License 
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 * 
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite 
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 * 
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 * 
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably 
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

package com.funambol.mailclient.syncml;

import com.funambol.util.ChunkedString;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Date;
import com.funambol.mail.Message;
import com.funambol.mail.MessageFlags;
import com.funambol.mail.MIMEFormatter;
import com.funambol.mail.MIMEProcessor;
import com.funambol.mail.MailException;

import com.funambol.util.Log;
import com.funambol.util.XmlUtil;
import com.funambol.util.StringUtil;
import com.funambol.util.MailDateFormatter;
import com.funambol.util.QuotedPrintable;
import com.funambol.util.XmlException;

/**
 * This class is able to parse and format the OMA-DS 1.2 Email object.
 */
class EmailData {

    // ------------------------------------------------------- Private data
    private static final String EMAIL_TAG = "Email";
    private static final String READ_TAG = "read";
    private static final String FORW_TAG = "forwarded" ;
    private static final String REPL_TAG = "replied" ;
    private static final String TREC_TAG = "received" ;
    private static final String TCRE_TAG = "created" ;
    private static final String TMOD_TAG = "modified" ;
    private static final String DELE_TAG = "deleted" ;
    private static final String FLAG_TAG = "flagged" ;
    private static final String ITEM_TAG = "emailitem" ;
    private static final String EXT_TAG  = "Ext" ;

    private static final String FOLDER_TAG = "Folder";
    private static final String ROLE_TAG = "role";

    private MessageFlags flags;
    
    private Date received;
    private Date created;
    private Date modified;

    private Message emailItem;


    // ------------------------------------------------------- Constructors

    /** 
     * Inizialize an empty instance
     */
    public EmailData() {
        flags = new MessageFlags();
        received = created = modified = null ;
        emailItem = null;
    }

    /** 
     * Initialize an instance taking the information from Message.
     */
    public EmailData(Message msg) {
        if (msg != null) {
            this.flags = msg.getFlags();
            this.received = msg.getReceivedDate();
            this.created = msg.getSentDate();
            this.modified = msg.getSentDate();
        }
        else {
            flags = new MessageFlags() ;
            received = created = modified = null ;
        }

        this.emailItem = msg;
    }

    // ---------------------------------------------------------- Accessors  
    
    /** Returns the message flags */
    public MessageFlags getFlags() { return flags; }
    /** Sets the message flags */
    public void setFlags(MessageFlags flags) { this.flags=flags; }

    /** Returns the received time */
    public Date getReceived() { return received; }
    /** Sets the received time */
    public void setReceived(Date v) { received=v; }

    /** Returns the created time */
    public Date getCreated() { return created; }
    /** Sets the created time */
    public void setCreated(Date v) { created=v; }

    /** Returns the modified time */
    public Date getModified() { return modified; }
    /** Sets the modified time */
    public void setModified(Date v) { modified=v; }

    /** 
     * Returns the Message contained in this Email object, if present
     */
    public Message getEmailItem() {
        return emailItem;
    }

    /** 
     * Set the emailItem Message in this Email object, to be sent out
     */
    public void setEmailItem(Message msg) {
        emailItem = msg;
    }

    // ----------------------------------------------------- Public Methods

    /**
     * Parse the Email item content.
     */
    public void parse(byte[] syncmlData)
                            throws XmlException, MailException {

	ChunkedString data = new ChunkedString(new String(syncmlData));

        ChunkedString xml = XmlUtil.getTagValue(data, EMAIL_TAG);
        data = null;
        flags.setFlag(MessageFlags.OPENED,    getXmlFlag(xml, READ_TAG));
        flags.setFlag(MessageFlags.FORWARDED, getXmlFlag(xml, FORW_TAG));
        flags.setFlag(MessageFlags.ANSWERED,  getXmlFlag(xml, REPL_TAG));
        flags.setFlag(MessageFlags.DELETED,   getXmlFlag(xml, DELE_TAG));
        flags.setFlag(MessageFlags.FLAGGED,   getXmlFlag(xml, FLAG_TAG));
        
        received = getXmlDate(xml, TREC_TAG);
        created =  getXmlDate(xml, TCRE_TAG);
        modified = getXmlDate(xml, TMOD_TAG);

        int itemPos = XmlUtil.getTag(xml, ITEM_TAG);
        if(itemPos > -1) {
            int begin = xml.indexOf(">", itemPos);
            if(xml.charAt(begin-1) == '/') {
                Log.debug("EmailData.parse: empty emailitem.");
                return;
            }
            int end = xml.indexOf("</"+ITEM_TAG+">", begin);
            if(begin == -1 || end == -1) {
                Log.error("[EmailData] error parsing EmailItem");
                throw new XmlException("Can't parse email item");
            }
            // FIXME: implement the CDATA handling in the Xml parser or use
            //        kxml
            int pos = xml.indexOf("<![CDATA[", begin);
            if (pos != -1) {
                begin = pos + 8;
                end = xml.indexOf("]]>", begin);
                if (end == -1) {
                    Log.error("[EmailData] can't find CDATA end.");
                    throw new XmlException("Can't find CDATA end.");
                }
            }
            ChunkedString item = xml.substring(begin+1, end);
            Hashtable attr = XmlUtil.getTagAttributes(xml, ITEM_TAG);
            //Log.debug("Retrieving encoding");
            String encoding = (String)attr.get("enc");
            // Try with Uppercase for 3.0 connector bug
            if(encoding == null) {
                encoding = (String)attr.get("ENC");
            }
            if(encoding != null) {
                Log.debug("EmailData.parse: encoding from server= " + encoding);
                if(StringUtil.equalsIgnoreCase(encoding,"quoted-printable")) {
                    // TODO: optimize this. Since the connector now does
                    //       not send QP to the client, we will not fall
                    //       into this case.
                    String qp = item.toString();
                    qp = QuotedPrintable.decode(qp.getBytes(), "UTF-8");
                    item = new ChunkedString(qp);
                }
            }
            // 
            MIMEProcessor mp = new MIMEProcessor();
            emailItem = mp.parseMailMessage(item);
            emailItem.setFlags(flags);

            // Process the Funambol extensions for filtering. Example:
            // <Ext><XNam>x-funambol-body</XNam><XVal>15000</XVal></Ext> 
            // <Ext><XNam>x-funambol-attach-n</XNam><XVal>1</XVal></Ext> 
            // <Ext><XNam>x-funambol-attach</XNam><XVal>att1.txt</XVal><XVal>10000</XVal></Ext>
            // XXX: we are now considering x-funambol-body only
            Vector extList = XmlUtil.getTagValues(xml, EXT_TAG);
            for(int i=0, l=extList.size(); i<l; i++) {
                ChunkedString ext = (ChunkedString)extList.elementAt(i);
                try {
                    ChunkedString xnam = XmlUtil.getTagValue(ext, "XNam");
                    if(xnam.equals("x-funambol-body")) {
                        String xval = XmlUtil.getTagValue(ext, "XVal").toString();
                        if (xval == null) {
                            Log.info("Incomplete header");
                        }
                        emailItem.getFlags().setFlag(MessageFlags.PARTIAL, true);
                        break;
                    }
                } catch (XmlException xe) {
                    xe.printStackTrace();
                    Log.error("[EmailData.parse]Invalid Ext field. Ignoring it");
                }
            }
        }
    }


    /**
     * Format the item content.
     */
    public byte[] format() {
        StringBuffer out = new StringBuffer();
        out.append("<Email>\n");
        addXmlFlag(out, READ_TAG, flags.isSet(MessageFlags.OPENED));
        addXmlFlag(out, FORW_TAG, flags.isSet(MessageFlags.FORWARDED));
        addXmlFlag(out, REPL_TAG, flags.isSet(MessageFlags.ANSWERED));
        addXmlFlag(out, DELE_TAG, flags.isSet(MessageFlags.DELETED));
        addXmlFlag(out, FLAG_TAG, flags.isSet(MessageFlags.FLAGGED));

        String utcdate = null;
        
        if(received != null){
            utcdate = MailDateFormatter.dateToUTC(received);
            XmlUtil.addElement(out, TREC_TAG, utcdate);
        }
        if(created != null){
            utcdate = MailDateFormatter.dateToUTC(created);
            XmlUtil.addElement(out, TCRE_TAG, utcdate);
        }
        if(modified != null) {
            utcdate = MailDateFormatter.dateToUTC(modified);
            XmlUtil.addElement(out, TMOD_TAG, utcdate);
        }
        
        if (emailItem != null) {
            MIMEFormatter mimef = new MIMEFormatter();
            out.append("<emailitem>\n<![CDATA[");
            // Append MIME representation of emailItem to out.
            mimef.format(emailItem, out);
            out.append("]]&gt;\n</emailitem>\n");
        }
        out.append("</Email>\n");

        return out.toString().getBytes();
    }

    //---------------------------------------------------------- Private methods

    private boolean getXmlFlag(ChunkedString xml, String tag) throws XmlException {
        ChunkedString val = null;

        if(XmlUtil.getTag(xml, tag) > -1) {
            val = XmlUtil.getTagValue(xml, tag);
            if(val.equals("true")) {
                return true;
            }
        }
        return false;
    }

    private void addXmlFlag(StringBuffer out, String tag, boolean flag) {
        String val = flag ? "true" : "false" ;
        XmlUtil.addElement(out, tag, val);
    }

    private Date getXmlDate(ChunkedString xml, String tag) throws XmlException {
        String val = null;
        MailDateFormatter df = new MailDateFormatter();

        if(XmlUtil.getTag(xml, tag) > -1) {
            val = XmlUtil.getTagValue(xml, tag).toString();
            return MailDateFormatter.parseUTCDate(val);
        }
        return null;
    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -