com.metadot.book.connectr.server.domain.StreamItem.java Source code

Java tutorial

Introduction

Here is the source code for com.metadot.book.connectr.server.domain.StreamItem.java

Source

/** 
 * Copyright 2010 Daniel Guermeur and Amy Unruh
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 *   See http://connectrapp.appspot.com/ for a demo, and links to more information 
 *   about this app and the book that it accompanies.
 */
package com.metadot.book.connectr.server.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.jdo.PersistenceManager;
import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;

import com.google.appengine.api.datastore.Text;
import com.metadot.book.connectr.server.utils.cache.CacheSupport;
import com.metadot.book.connectr.server.utils.cache.Cacheable;
import com.metadot.book.connectr.shared.StreamItemDTO;
import com.metadot.book.connectr.shared.StreamItemSummaryDTO;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndImage;
import com.sun.syndication.feed.synd.SyndLink;
import com.sun.syndication.feed.synd.SyndPerson;

/**
 * The StreamItem persistence-capable class holds information about feed items. 
 * Objects from this class form the basis of the 'activity stream' display.
 */
@SuppressWarnings("serial")
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class StreamItem implements Serializable, Cacheable {

    private static final int CACHE_EXPIR = 1440 * 60; // expire the stream items after 24 hours, in seconds
    private static final int SUMMARY_LENGTH = 246; // length of the summary text

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    @Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
    private String id;

    @Persistent
    @Extension(vendorName = "datanucleus", key = "gae.pk-name", value = "true")
    private String url; // this field defines the 'key name' portion of the key

    // we do not need to index every field of the StreamItem objects,
    // so we mark some as 'unindexed'

    @Persistent
    private String title;
    @Persistent
    @Extension(vendorName = "datanucleus", key = "gae.unindexed", value = "true")
    private Text description;

    @Persistent
    @Extension(vendorName = "datanucleus", key = "gae.unindexed", value = "true")
    private String descrSummary;

    @Persistent
    @Extension(vendorName = "datanucleus", key = "gae.unindexed", value = "true")
    private String feedDescription;

    @Persistent
    private String feedUrl;

    @Persistent
    @Extension(vendorName = "datanucleus", key = "gae.unindexed", value = "true")
    private String imageUrl;

    @Persistent
    @Extension(vendorName = "datanucleus", key = "gae.unindexed", value = "true")
    private String feedTitle;
    @Persistent
    @Extension(vendorName = "datanucleus", key = "gae.unindexed", value = "true")
    private String author;

    @Persistent
    private Date date;

    @Persistent
    Set<Long> ukeys;

    public StreamItem() {
    }

    public StreamItem(String title, String description, String feedDescription, Date date, String feedTitle,
            String author, String url, String feedUrl, String imageUrl, Set<Long> ukeys) {
        this();
        this.title = title;
        this.description = new Text(description);
        this.feedDescription = feedDescription;
        this.date = date;
        this.author = author;
        this.feedTitle = feedTitle;
        this.url = url;
        this.feedUrl = feedUrl;
        this.imageUrl = imageUrl;
        this.descrSummary = null;
        this.ukeys = ukeys;

    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getTitle() {
        return title;
    }

    public void setDescription(String description) {
        this.description = new Text(description);
    }

    public Text getDescription() {
        return description;
    }

    public String getId() {
        return id;
    }

    public Set<Long> getUkeys() {
        return ukeys;
    }

    public void setUkeys(Set<Long> ukeys) {
        this.ukeys = ukeys;
    }

    public String getFeedDescription() {
        return feedDescription;
    }

    public void setFeedDescription(String feedDescription) {
        this.feedDescription = feedDescription;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getFeedUrl() {
        return feedUrl;
    }

    public void setFeedUrl(String feedUrl) {
        this.feedUrl = feedUrl;
    }

    public String getImageUrl() {
        return imageUrl;
    }

    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }

    public String getFeedTitle() {
        return feedTitle;
    }

    public void setFeedTitle(String feedTitle) {
        this.feedTitle = feedTitle;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public StreamItemDTO toDTO() {
        return new StreamItemDTO(id, url, title, description.getValue(), descrSummary, feedDescription, feedUrl,
                imageUrl, feedTitle, author, date);
    }

    public void removeFromCache() {
        CacheSupport.cacheDelete(this.getClass().getName(), id);
    }

    private String buildDescrSummary() {

        String cleaned = Jsoup.clean(description.getValue(), Whitelist.none());
        if (cleaned.length() > SUMMARY_LENGTH) {
            this.descrSummary = cleaned.substring(0, SUMMARY_LENGTH - 1) + "...";
        } else {
            this.descrSummary = cleaned;
        }
        return this.descrSummary;
    }

    private String getDescrSummary() {

        if (this.descrSummary != null) {
            return this.descrSummary;
        } else {
            return buildDescrSummary();
        }
    }

    /**
     * returns list of feed entries converted to StreamItem objects
     */
    public static List<String> buildItems(FeedInfo fi, PersistenceManager pm) {

        Set<Long> ukeys = fi.getUkeys();
        SyndFeed sf = fi.getFeedInfo().getSyndFeed();
        @SuppressWarnings("unchecked")
        List<SyndEntry> entries = sf.getEntries();
        StreamItem item;
        for (SyndEntry entry : entries) {
            item = StreamItem.buildItem(fi.getUrl(), sf, entry, ukeys);
            pm.makePersistent(item);
        }
        return null;
    }

    /**
     * convert a feed entry to a StreamItem
     */
    @SuppressWarnings("unchecked")
    private static StreamItem buildItem(String urlstring, SyndFeed sf, SyndEntry entry, Set<Long> ukeys) {

        StreamItem item = null;
        String title = "", url = "", description = "", feedDescription = "", feedTitle = "", author = "",
                imageUrl = "";
        Date date = null;
        String descr = null;

        try {
            // gather all the information.....
            url = entry.getLink();
            date = entry.getPublishedDate();
            feedTitle = sf.getTitle();
            feedDescription = sf.getDescription();
            title = Jsoup.clean(entry.getTitle(), Whitelist.simpleText());
            // for twitter, first remove the leading author string
            if (url.contains("twitter.com")) {
                int cindex = title.indexOf(":");
                if (cindex > 0) {
                    title = title.substring(cindex + 1);
                }
            }
            if (entry.getDescription() != null) {
                descr = entry.getDescription().getValue();
            }
            if (descr == null) {
                if (entry.getContents().size() > 0) {
                    SyndContent content = (SyndContent) entry.getContents().get(0);
                    if (content.getType().equalsIgnoreCase("html")) {
                        descr = content.getValue();
                    }
                }
            }
            if (descr != null) {
                // sanitize the content 
                description = Jsoup.clean(descr, Whitelist.basicWithImages());
            }

            List<SyndPerson> sauthors = entry.getAuthors();
            List<String> auths = new ArrayList<String>();
            for (SyndPerson auth : sauthors) {
                auths.add(auth.getName());
            }
            author = StringUtils.join(auths, ", ");
            SyndImage eImg = sf.getImage();
            if (eImg != null) {
                imageUrl = eImg.getUrl();
            } else {
                // if twitter link... 
                if (url.contains("twitter.com")) {
                    // then see if a second link is available-- if so, it should be the link to the image
                    List<SyndLink> links = entry.getLinks();
                    if (links.size() >= 2) {
                        SyndLink imgl = links.get(1);
                        imageUrl = imgl.getHref();
                    }
                }
            }
            item = new StreamItem(title, description, feedDescription, date, feedTitle, author, url, urlstring,
                    imageUrl, ukeys);
            item.buildDescrSummary();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return item;
    }

    public StreamItemSummaryDTO buildSummaryItem() {
        String descrSummary = getDescrSummary();
        StreamItemSummaryDTO summ = new StreamItemSummaryDTO(id, title, url, descrSummary, date, author, imageUrl);
        return summ;
    }

    public StreamItemSummaryDTO addToCacheGetSumm() {
        CacheSupport.cachePutExp(this.getClass().getName(), id, this, CACHE_EXPIR);
        return addSummaryToCache();
    }

    public void addToCache() {
        CacheSupport.cachePutExp(this.getClass().getName(), id, this, CACHE_EXPIR);
        addSummaryToCache();
    }

    public StreamItemSummaryDTO addSummaryToCache() {
        StreamItemSummaryDTO summ = buildSummaryItem();
        CacheSupport.cachePut(StreamItemSummaryDTO.class.getName(), summ.getId(), summ);
        return summ;
    }
}