Site icon Soul & Shell Blog

iCal Applicatoin - iCal Java API 研究與教學

iCal Introduction

iCal是由Apple所發佈的一種數據交換格式,其前身為iCalendar。iCal主要是一種資料交換格式,專門用來針對行事曆管理、事件發佈。把活動用ICAL發佈主要的好處是可以跟各種線上日曆、支援ICAL的手機/PDA做結合。

iCal Feed

iCal的資料格式稱為Feed,通常以副檔名*.ics或者xml的方式存在,目前已有許多api支援各種程式的設計。

發布
目前最常使用email

行事曆
目前最廣泛的應用為行事曆,由於iCal的核心在於事件與時間之間的關係,因此最近常應用在發佈會議等通知上,像是Google Calendar, Tounderbird Calendar, Msn Calender, M$ Outlook 2007, Windows vista行事曆... 等等行事曆管理軟體中都可以出現iCal的身影。

事件應用
iCal的事件應用像是在場地的租借,通知會議,生日節慶通知,群體公告發布,總而言之與"時間性"相關的應用才是iCal的精隨。

iCal Implements

網路上有許多已經設計好的feed可供下載
icalshare
無意間看到了農民曆,來玩看看吧
農民曆下載網址:http://icalshare.com/article.php?story=20061228050113376

Tounderbird 安裝

email發佈事件
經過測試後,只要在mail的夾檔中加入想發佈的 feed (.ics檔案) 就可以讓web mail觸發事件,但是目前 Java 上的 API ical4j 產出的檔案不被接受,這個部分要在測試。

iCal Format

Feed的格式參照RFC 2445[http://tools.ietf.org/html/rfc2445]
檔案格式如下

*.ics檔案格式

BEGIN:VCALENDAR
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0
METHOD:REQUEST
BEGIN:VTIMEZONE
TZID:Asia/Taipei
X-LIC-LOCATION:Asia/Taipei

BEGIN:STANDARD
TZOFFSETFROM:+0800
TZOFFSETTO:+0800
TZNAME:CST
DTSTART:19700101T000000
END:STANDARD

END:VTIMEZONE

BEGIN:VEVENT
CREATED:20081015T091126Z
LAST-MODIFIED:20081015T091149Z
DTSTAMP:20081015T091149Z
UID:91d12aff-9b91-44e8-8924-eebb92691e22
SUMMARY:test3
ORGANIZER;RSVP=TRUE;CN=sj;PARTSTAT=ACCEPTED;ROLE=CHAIR:mailto:
 sj@sj.com

ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:
 sj@sj.com

DTSTART;TZID=Asia/Taipei:20081015T180000
DTEND;TZID=Asia/Taipei:20081015T190000
LOCATION:123
DESCRIPTION:123
SEQUENCE:0
END:VEVENT

END:VCALENDAR

iCal檔簡述

基本上iCal有點像是html, 使用BEGIN與END來包圍, 最外層是VCALENDAR, 而內部有許多元件組成, 如此的元件像是VEVENT,VTIMEZONE.....等等.
一個VCALENDAR允許包含許多相同的元件, 也可以使用Base64編碼加入物件檔案, 如下

ATTACH:http://xyz.com/public/quarterly-report.doc

ATTACH;FMTTYPE=image/basic;ENCODING=BASE64;VALUE=BINARY:
MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1U
EBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIE
<...remainder of "BASE64" encoded binary data...>

email傳送

要使用email傳送iCal必須在mail中加入一項MimeBody, 如下

Content-Type: text/calendar; charset=us-ascii
Content-Transfer-Encoding: 7bit

 

重點在"Content-Type: text/calendar",當我們的MUA(Mail User Agent,像是Outlook,Sunbird,Web Mail)看到這個MimeBody時, 就會解析其中的內容並且產生對應動作

iCal Example Java Code

import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;

public class MailCalendar {

    Session session = null;
    private Message ms_msg;
    private Multipart multi_msg_part;
    private StringBuffer ms_strbufMsg;
    public static String ms_strSMTPHost = "smtp.server.com"; // 預設SMTP Server

    public void send(String strFrom, // sender
            String[] astrTo, // recipient(s)
            String strSubject, // subject
            String strContent, // content
            String paths[], boolean debugging) {
        String ms_strFrom = strFrom; // who the message is from
        String[] ms_astrTo = astrTo; // who (plural) the message is to
        boolean ms_debugging = debugging;

        // set the host
        Properties props = new Properties();
        // props.put("mail.smtp.host", this.ms_strSMTPHost);
        props.put("mail.smtp.auth", "true");

        // create some properties and get the default Session
        session = Session.getDefaultInstance(props, null);
        session.setDebug(ms_debugging);

        try {

            // create a message
            this.ms_msg = new MimeMessage(session);

            // set the from
            InternetAddress from = new InternetAddress(strFrom);
            this.ms_msg.setFrom(from);

            InternetAddress[] address = null;
            // set the to
            if (astrTo != null) {
                address = new InternetAddress[astrTo.length];
                for (int i = 0; i < astrTo.length; ++i) {
                    address[i] = new InternetAddress(astrTo[i]);
                }
                this.ms_msg.setRecipients(Message.RecipientType.TO, address);
            }

            // set the subject
            this.ms_msg.setSubject(strSubject);

            // set up the string buffer which will hold the message
            this.ms_strbufMsg = new StringBuffer();
            this.ms_strbufMsg.append(strContent);

            // create and fill the first message part
            MimeBodyPart mbp1 = new MimeBodyPart();
            // mbp1.setText(new String(ms_strbufMsg));
            mbp1.setContent(new String(ms_strbufMsg), "text/html;charset=Big5");

            this.multi_msg_part = new MimeMultipart();
            this.multi_msg_part.addBodyPart(mbp1);

            if (paths != null) {
                MimeBodyPart mbp2 = null;
                File file = null;
                FileDataSource fds = null;

                for (int i = 0; i < paths.length; i++) {
                    // create the second message part
                    mbp2 = new MimeBodyPart();
                    // attach the file to the message
                    String filename = paths[i];
                    file = new File(paths[i]);
                    if (file.exists()) {
                        fds = new FileDataSource(file);
                        mbp2.setDataHandler(new DataHandler(fds));
                        mbp2.setFileName(fds.getName());
                        this.multi_msg_part.addBodyPart(mbp2);
                    }
                }
                file = null;
            }

            try {
                // set the content
                this.ms_msg.setContent(this.multi_msg_part);
                // set the Date: header
                this.ms_msg.setSentDate(new Date());

                // and away
                // Transport.send(this.ms_msg);

                Transport transport = session.getTransport("smtp");
                transport.connect(ms_strSMTPHost, "sj", "1234");
                transport.sendMessage(this.ms_msg,
                        this.ms_msg.getAllRecipients());
                transport.close();

                System.out.println("Mail Send");
            } catch (Exception ex) {
                System.out.println("Caught exception in MailSender.ms_send: "
                        + ex);
            }

        } catch (MessagingException mex) {
            mex.printStackTrace(System.err);
        } catch (Exception ex) {
            ex.printStackTrace(System.err);
        }
    }

}

使用JavaMail API設計能夠讓Gmail,Thunderbird觸發會議邀請事件的email message

Exit mobile version