Package org.ryu22e.nico2cal.service

Source Code of org.ryu22e.nico2cal.service.CalendarService

package org.ryu22e.nico2cal.service;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.LinkedList;
import java.util.List;
import java.util.TimeZone;
import java.util.logging.Logger;

import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.model.DateTime;
import net.fortuna.ical4j.model.PropertyList;
import net.fortuna.ical4j.model.component.VEvent;
import net.fortuna.ical4j.model.property.Description;
import net.fortuna.ical4j.model.property.DtEnd;
import net.fortuna.ical4j.model.property.DtStart;
import net.fortuna.ical4j.model.property.ProdId;
import net.fortuna.ical4j.model.property.Summary;
import net.fortuna.ical4j.model.property.Url;
import net.fortuna.ical4j.model.property.Version;
import net.fortuna.ical4j.model.property.XProperty;

import org.ryu22e.nico2cal.meta.NicoliveIndexMeta;
import org.ryu22e.nico2cal.meta.NicoliveMeta;
import org.ryu22e.nico2cal.model.Nicolive;
import org.ryu22e.nico2cal.model.NicoliveIndex;
import org.ryu22e.nico2cal.util.HtmlRemoveUtil;
import org.slim3.datastore.Datastore;
import org.slim3.datastore.ModelQuery;
import org.slim3.util.DateUtil;
import org.slim3.util.TimeZoneLocator;
import org.xml.sax.SAXException;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Query.SortDirection;

/**
* iCalendarファイルを操作するサービスクラス。
* @author ryu22e
*
*/
public final class CalendarService {

    /**
     *
     */
    private static final Logger LOGGER = Logger.getLogger(CalendarService.class
        .getName());

    /**
     *
     */
    private static final ProdId PROD_ID = new ProdId("nico2ical");

    /**
     *
     */
    private static final String CALNAME = "ニコニコ生放送";

    /**
     * リスト1とリスト2の同じ要素をマージする。
     * @param <T> 型名
     * @param list1 リスト1
     * @param list2 リスト2
     * @return マージされたリスト
     */
    private <T> List<T> merge(List<T> list1, List<T> list2) {
        List<T> merged = new LinkedList<T>();
        if (list1.size() <= 0) {
            merged.addAll(list2);
        } else if (list2.size() <= 0) {
            merged.addAll(list1);
        } else {
            for (T t : list1) {
                if (list2.contains(t)) {
                    merged.add(t);
                }
            }
        }
        return merged;
    }

    /**
     * Datastoreに登録されたRSSフィードをiCalendar形式のデータに変換する。
     * @param condition 検索条件
     * @return iCalendar形式のデータ
     * @throws NullPointerException パラメータがnullの場合。
     * @throws IllegalArgumentException 検索条件にStartDateが指定されていない場合。
     */
    public Calendar getCalendar(CalendarCondition condition) {
        if (condition == null) {
            throw new NullPointerException("condition is null.");
        }
        if (condition.getStartDate() == null) {
            throw new IllegalArgumentException("StartDate is null.");
        }

        Calendar calendar = new Calendar();
        calendar.getProperties().add(PROD_ID);
        calendar.getProperties().add(Version.VERSION_2_0);
        calendar.getProperties().add(new XProperty("X-WR-CALNAME", CALNAME));

        NicoliveMeta n = NicoliveMeta.get();
        NicoliveIndexMeta ni = NicoliveIndexMeta.get();

        ModelQuery<Nicolive> query =
                Datastore
                    .query(n)
                    .filter(
                        n.openTime.greaterThanOrEqual(condition.getStartDate()))
                    .sort(n.openTime.getName(), SortDirection.ASCENDING);

        if (condition.getKeywords() != null
                && 0 < condition.getKeywords().size()) {
            List<Key> keywordKeys = new LinkedList<Key>();
            for (String keyword : condition.getKeywords()) {
                List<NicoliveIndex> indexes =
                        Datastore
                            .query(ni)
                            .filter(ni.keyword.equal(keyword))
                            .asList();
                List<Key> keys = new LinkedList<Key>();
                for (NicoliveIndex nicoliveIndex : indexes) {
                    keys.add(nicoliveIndex.getNicoliveKey());
                }
                keywordKeys = merge(keys, keywordKeys);
            }
            if (0 < keywordKeys.size()) {
                query = query.filterInMemory(n.key.in(keywordKeys));
            } else {
                // キーワード検索で該当するエンティティがなければ、この後のクエリを発行する必要がないので、ここで検索を終了とする。
                return calendar;
            }
        }

        TimeZone timezone = TimeZoneLocator.get();
        List<Nicolive> nicolives = query.asList();
        for (Nicolive nicolive : nicolives) {
            PropertyList properties = new PropertyList();
            properties.add(new Summary(nicolive.getTitle()));
            String description;
            try {
                description =
                        HtmlRemoveUtil.removeHtml(nicolive
                            .getDescription()
                            .getValue());
            } catch (SAXException e1) {
                description = "";
            } catch (IOException e1) {
                description = "";
            }
            java.util.Calendar c = DateUtil.toCalendar(nicolive.getOpenTime());
            c.setTimeZone(timezone);
            properties.add(new Description(description));
            properties.add(new DtStart(new DateTime(c.getTime()), true));
            properties.add(new DtEnd(new DateTime(c.getTime()), true));
            try {
                URI uri = new URI(nicolive.getLink().getValue());
                properties.add(new Url(uri));
            } catch (URISyntaxException e) {
                LOGGER.warning(e.getMessage());
            }

            VEvent event = new VEvent(properties);
            calendar.getComponents().add(event);
        }

        return calendar;
    }

}
TOP

Related Classes of org.ryu22e.nico2cal.service.CalendarService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.