2011年6月2日木曜日

eclipselink を使う :(8)機能を追加する

前回までで、eclipselink を使った基本的な機能の追加を行いました。これらの機能を組み合わせて、データのインポート/エクスポート、簡単な問い合わせなどの処理を行うことができます。今はスマートフォンやタブレットPCで便利な連絡先管理ツールを使うことができますが、自分で作れば、色々なデータと自由に連携させて自分の使い方に合ったツールにすることが可能です。

インポート機能を追加する
ContactHome に、以下のメソッドを追加します:
    public List<Contact> importVCards(String path, String username,
            File[] vcards) {
        List<Contact> contacts = new ArrayList<Contact>(vcards.length);
        try {
            for (File file : vcards) {
                contacts.add(readFromVCard(file.getAbsolutePath(), username));
            }

        } catch (Exception e) {
            DBActivator.log("vCard からインポートに失敗:" + e.getMessage());
        }
        return contacts;
    }

    public static Contact readFromVCard(InputStream is, String username) {
        Contact contact = new Contact();
        contact.setUsername(username);
        BufferedReader bufferedReader = null;
        String charSet = "MS932";

        // vCard を解析する
        try {
            InputStreamReader inputStreamReader = new InputStreamReader(is, charSet);
            bufferedReader = new BufferedReader(inputStreamReader);
            String line;
            String value;
            while ((line = bufferedReader.readLine()) != null) {
                // -- 名前
                value = getVCardValue(line, "N");
                if (value != null) {
                    String[] result = value.split(";");
                    StringBuilder simei = new StringBuilder();
                    StringBuilder yomi = new StringBuilder();
                    if (result.length > 0) {
                        int st = result[0].indexOf('<');
                        int ed = result[0].indexOf('>');
                        if (st >= 0 && ed > 0) {
                            yomi.append(result[0].substring(st + 1, ed).trim());
                            simei.append(result[0].substring(ed + 1).trim());
                        } else {
                            simei.append(result[0]);
                        }
                    }
                    if (result.length > 1) {
                        int st = result[1].indexOf('<');
                        int ed = result[1].indexOf('>');
                        if (st >= 0 && ed > 0) {
                            yomi.append(" ").append(
                                    result[1].substring(st + 1, ed).trim());
                            simei.append(" ").append(
                                    result[1].substring(ed + 1).trim());
                        } else {
                            simei.append(" ").append(result[1]);
                        }
                    }
                    contact.setSimei(simei.toString());
                    contact.setYomi(yomi.toString());
                    if (result.length > 3) {
                        contact.setTitle(result[3]);
                    }
                    continue;
                }
                // -- 電話
                value = getVCardValue(line, "TEL;HOME");
                if (value != null && value.trim().length()>0) {
                    value = value.replaceAll("-", "");
                    System.out.println("HOME:" + value);
                    contact.getPhones().put("自宅",
                            new Phone(contact, value, "自宅"));
                    continue;
                }
                value = getVCardValue(line, "TEL;WORK");
                if (value != null && value.trim().length()>0) {
                    value = value.replaceAll("-", "");
                    System.out.println("WORK:" + value);
                    contact.getPhones().put("勤務先",
                            new Phone(contact, value, "勤務先"));
                    continue;
                }
                value = getVCardValue(line, "TEL;CELL");
                if (value != null && value.trim().length()>0) {
                    value = value.replaceAll("-", "");
                    System.out.println("CELL:" + value);
                    contact.getPhones().put("携帯",
                            new Phone(contact, value, "携帯"));
                    continue;
                }
                // -- 住所
                value = getVCardValue(line, "ADR;HOME");
                if (value != null) {
                    setAddress(contact, value, "自宅");
                    continue;
                }
                value = getVCardValue(line, "ADR;WORK");
                if (value != null) {
                    setAddress(contact, value, "勤務先");
                    continue;
                }
                // -- メール
                value = getVCardValue(line, "EMAIL;PREF;INTERNET");
                if (value != null && value.trim().length()>0) {
                    setMail(contact, value, "自宅");
                    continue;
                }
                // -- WEBページ
                value = getVCardValue(line, "URL;HOME");
                if (value != null && value.trim().length()>0) {
                    setWebpage(contact, value, "自宅");
                    continue;
                }
                value = getVCardValue(line, "URL;WORK");
                if (value != null && value.trim().length()>0) {
                    setWebpage(contact, value, "勤務先");
                    continue;
                }
                // -- 性別
                value = getVCardValue(line, "X-WAB-GENDER");
                if (value != null) {
                    if (value.equals("1")) {
                        contact.setSeibetu("女");
                    } else if (value.equals("2")) {
                        contact.setSeibetu("男");
                    }
                    continue;
                }
                value = getVCardValue(line, "ORG");
                if (value != null && value.length() > 0) {
                    contact.setCompany(value);
                    contact.setContactType(ContactType.SIGOTO);
                    continue;
                }
                value = getVCardValue(line, "TITLE");
                if (value != null) {
                    contact.setJobTitle(value);
                    continue;
                }
                // -- メモ
                value = getVCardValue(line, "NOTE");
                if (value != null) {
                    for (ContactType type: ContactType.values()) {
                        String syubetu = "種別("+type.toString()+")";
                        int idx = value.indexOf(syubetu); 
                        if ( idx >= 0) {
                            //メモに種別が書かれていたら連絡先にセットして、メモからは除く
                            //注意:2種類以上書かれている場合をチェックしていない
                            contact.setContactType(type);
                            value = value.substring(idx+syubetu.length());
                            break;
                        }
                    }
                    //種別を除くメモのみを設定
                    contact.setNote(value);
                    continue;
                }
                // -- 誕生日
                value = getVCardValue(line, "BDAY");
                if (value != null) {
                    Calendar cal = Calendar.getInstance();
                    int yy = Integer.parseInt(value.substring(0, 4));
                    int mm = Integer.parseInt(value.substring(4, 6));
                    int dd = Integer.parseInt(value.substring(6, 8));
                    cal.set(Calendar.YEAR, yy);
                    cal.set(Calendar.MONTH, mm);
                    cal.set(Calendar.DAY_OF_MONTH, dd);
                    contact.setSeinengappi(cal.getTime());
                    continue;
                }
                // -- 写真
                value = getVCardValue(line, "PHOTO;TYPE=JPEG;ENCODING=BASE64");
                if (value != null) {
                    line = bufferedReader.readLine();
                    StringBuilder builder = new StringBuilder();
                    while (line != null && line.length() > 0
                            && line.charAt(0) == ' ') {
                        builder.append(line.trim());
                        line = bufferedReader.readLine();
                    }
                    String jpegString = builder.toString();
                    // 取得した Jpeg文字列のまま保存
                    contact.setJpegString(jpegString);
                    continue;
                }
            }
        } catch (IOException e) {
            DBActivator.log("VCard リードエラー", e);
        } finally {
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
            } catch (IOException e) {
                DBActivator.log("VCard リードエラー", e);
            }
        }
        return contact;
    }

    private static void setAddress(Contact contact, String value, String addressType) {
        String[] result = value.split(";");
        if (result.length==0) return;
        
        Address address = new Address();
        address.setAddressType(addressType);
        address.setContact(contact);

        address.setBanchi2("");
        if (result.length > 2) {
            address.setBanchi(result[2]);
        }
        if (result.length > 3) {
            address.setSikuchoson(result[3]);
        }
        if (result.length > 4) {
            address.setTodofuken(result[4]);
        }
        if (result.length > 5) {
            String yubin = result[5].trim().replace("-", "");
            address.setYubin(yubin);
        }
        if (result.length > 6) {
            // 国の情報は無視
        }
        contact.getAddresses().put(addressType, address);
    }

    private static void setMail(Contact contact, String value, String addressType) {
        Address address = contact.getAddresses().get(addressType);
        if (address == null) {
            address = new Address();
            address.setAddressType(addressType);
            address.setContact(contact);
            address.setMail(value);
            contact.getAddresses().put(addressType, address);
        } else {
            address.setMail(value);
        }
    }

    private static void setWebpage(Contact contact, String value, String addressType) {
        Address address = contact.getAddresses().get(addressType);
        if (address == null) {
            address = new Address();
            address.setAddressType(addressType);
            address.setContact(contact);
            address.setWebpage(value);
            contact.getAddresses().put(addressType, address);
        } else {
            address.setWebpage(value);
        }
    }

    /**
     * 指定行が指定トークンを持つならトークン以降の値を取り出して返す.
     * 
     * @param line
     *            行
     * @param token
     *            トークン
     * @return 取得した値 | null(行がトークンを持っていない場合)
     */
    private static String getVCardValue(String line, String token) {
        if (line.startsWith(token + ":") || line.startsWith(token + ";")) {
            String value = line.substring(line.indexOf(":") + 1);
            return value;
        }
        return null;
    }


このメソッドは、VCard からテスト用のデータを読み込んで List を返します。各 Contact インスタンスを、ContactHome#add()メソッドを使ってデータベースに保存します。


Google Data API を使って、グーグル連絡先からのインポート機能を追加することもできます。

エディタを追加する
次は、連絡先データを編集するためのエディタを追加します。plugin.xml の拡張ページで、org.eclipse.ui.editors 拡張ポイントを追加して、エディタを定義します。com.itrane.mycontact.ui.editors.ContactEditor も作成します。


その他の機能
以前ブログに書いた乗換え案内宛名印刷などの機能を追加することもできます。




0 件のコメント: