Package talkfeed

Source Code of talkfeed.UserManager

/*
Copyright 2010/2012 - Jean-Baptiste Vovau

   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.
*/

package talkfeed;

import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import talkfeed.QueuedTask.TaskType;
import talkfeed.cache.CacheService;
import talkfeed.cache.UserPresence;
import talkfeed.data.Blog;
import talkfeed.data.BlogEntry;
import talkfeed.data.DataManager;
import talkfeed.data.DataManagerFactory;
import talkfeed.data.Subscription;
import talkfeed.data.User;
import talkfeed.url.UrlShortenFactory;
import talkfeed.utils.Logs;
import talkfeed.utils.TextTools;
import talkfeed.xmpp.JabberBlogNotification;
import talkfeed.xmpp.TalkService;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.xmpp.JID;
import com.google.appengine.api.xmpp.Presence;

/**
* Send subscription via user
*
* @author Balmeyer
*
*/
public class UserManager {

  private static final int NB_SUBSCRIPTIONS_MAX = 20;

  private PersistenceManager currentManager;

  /**
   * Get or create user
   * @param jid
   * @return
   */
  public User getOrCreateUser(String jid){
   
    DataManager dm = DataManagerFactory.getInstance();
    PersistenceManager pm = dm.newPersistenceManager();
   
    User user = dm.getUserFromId(pm , jid);
    if (user == null){
      user = new User();
      user.setId(jid);
      user.setDateCrea(new Date());
      user.setNextUpdate(new Date());
      pm.currentTransaction().begin();
      pm.makePersistent(user);
      pm.currentTransaction().commit();
    }
   
   
    pm.close();
    pm = null;
   
    return user;
  }
 
  /**
   * Modify user presence in GTalk
   * @param id
   * @param presence
   */
  public void setUserPresence(String id , Presence presence){
    if (id == null) return;
   
    Logs.info("Presence for ID : " + id);
   
    UserPresence.setUserPresence(id, presence);
  }
 
  /**
   * Send notification for users
   * @param nbMax
   */
  @SuppressWarnings("unchecked")
  public void updateUsers(int nbMax) {

    Date now = Calendar.getInstance().getTime();

    PersistenceManager pm = DataManagerFactory.getInstance()
        .newPersistenceManager();


    // find user
    Query q = pm.newQuery(User.class);
    q.setFilter("nextUpdate <= next && paused == false && presence == 'available'");
    q.setOrdering("nextUpdate");
    q.declareParameters("java.util.Date next");
    q.setRange(0, nbMax);

    // list user
    List<User> list = (List<User>) q.execute(now);

    for (User user : list) {
      //build task for queuing
      QueuedTask task = new QueuedTask();
      task.setType(TaskType.updateuser);
      task.addParam("id", user.getKey().getId());
      QueuedTask.enqueue(task);


    }

    // end of process
    q.closeAll();
    pm.close();

  }

  /**
   * Send notification for present users
   */
  public void updatePresentUsers(){

    Collection<String> users = UserPresence.listUserByNextUpdate(14);
    for(String user : users){
      //build task for queuing
      QueuedTask task = new QueuedTask();
      task.setType(TaskType.updateuser);
      task.addParam("jid", user);
      QueuedTask.enqueue(task);
    }
  }
 
  /**
   * Send notification to user if presence in gtalk is 'available'
   *
   * @param id
   */
  public void updateUser(long id, String email) {
   
    email = TextTools.cleanJID(email);
   
    // Nowadays
    Date now = Calendar.getInstance().getTime();

    // create new persistenceManager
    this.currentManager = DataManagerFactory.getInstance()
        .newPersistenceManager();

    //fetch user from his jabber id
    User user = null;
   
    if (id >0) {
      //fetch by id
      user = (User) this.currentManager.getObjectById(User.class, id);
    } else {
      //find by email
      if(email != null){
        user = this.getOrCreateUser(email);
      }
    }

    //user error
    if (user == null){
      throw new IllegalArgumentException("NO user found : id="
            + id + ", email=" +email);
    }
   
    // next update
    int minuteNextUpdate = user.getInterval();
    if (minuteNextUpdate < 10)
      minuteNextUpdate = 10;

    // test user presence
    JID jid = new JID(user.getId());
   
    boolean isAvailable = UserPresence.isUserAvailable(jid.getId());
   
    if (isAvailable) {
      //user is present : do update !

      // select subscriptions
      Query q = this.currentManager.newQuery(Subscription.class);
      q.setOrdering("lastProcessDate");
      q.setRange(0, NB_SUBSCRIPTIONS_MAX);
      q.setFilter("userKey == uk");
      q.declareParameters("com.google.appengine.api.datastore.Key uk");

      @SuppressWarnings("unchecked")
      List<Subscription> subs = (List<Subscription>) q.execute(user
          .getKey());

      // update
      for (Subscription sub : subs) {
        // update is done ?
        boolean updateDone = false;

        // fetch blog
        Blog blog = (Blog) this.currentManager.getObjectById(
            Blog.class, sub.getBlogKey());

        // compare dates bet blog last entry and subscription update
        if (blog.getLatestEntry().after(sub.getLatestEntryNotifiedDate())) {
          Logger.getLogger("UserService").info(
              "user " + user.getId() + " present. Try notify : "
                  + blog.getTitle());

          // find next entry
          BlogEntry nextEntry = this.findNextEntry(sub);

          if (nextEntry == null) {
            // subscription is up to date
          } else {
            // notify user
            this.sendBlogEntry(jid, nextEntry);
            // set modification is done
            updateDone = true;
            // set current subscription mark to entry date
            sub.setLatestEntryNotifiedDate(nextEntry.getPubDate());
          }
        }

        // Update subscription process
        // last analyze date
        sub.setLastProcessDate(now);
        this.currentManager.currentTransaction().begin();
        this.currentManager.flush();
        this.currentManager.currentTransaction().commit();

        // break
        if (updateDone) {
          // update user
          user.setLastUpdate(now);
          user.setLastSubscriptionKey(sub.getKey());
          this.currentManager.currentTransaction().begin();
          this.currentManager.flush();
          this.currentManager.currentTransaction().commit();
          break;
        }else {
          //nothing to update
          Logger.getLogger("UserService").info(
              "user " + user.getId() + " present but nothing to update.");
        }

      }

      q.closeAll();

    } else {
      /*
       * removed for XMPP issues
      minuteNextUpdate = 30;
      //remove from presence
      UserPresence.setPresence(user.getId(), presence);
      Logger.getLogger("UserService").info(
          "user " + user.getId() + " not present");
      */
    }

    // next update
    // record next update
    Calendar nextTime = Calendar.getInstance();
    nextTime.add(Calendar.MINUTE, minuteNextUpdate);
    user.setNextUpdate(nextTime.getTime());
    UserPresence.setNextUpdate(user.getId(), minuteNextUpdate);

    // flush
    this.currentManager.currentTransaction().begin();
    this.currentManager.flush();
    this.currentManager.currentTransaction().commit();

    this.currentManager.close();
    this.currentManager = null;
  }

  /**
   * Update when user id is unkwnown
   * @param email
   */
  public void updateUser(String email){
   
    email = TextTools.cleanJID(email);
   
    // test user presence
    //JID jid = new JID(email);
    //boolean isAvailable = UserPresence.isUserAvailable(jid.getId());

    //has a new subscription ?
    boolean hasNewSub = false;

    this.updateUser(0, email);

   
    //IF UPDATE : set user has received update !
    int minutes = (hasNewSub) ? 10 : 20 ;
    UserPresence.setNextUpdate(email, minutes);
  }

  /**
   * Remove a subscription
   *
   * @param id
   * @return
   */
  public boolean removeUserSubscription(long id) {

    DataManager dm = DataManagerFactory.getInstance();
    PersistenceManager pm = dm.newPersistenceManager();

    Subscription s = pm.getObjectById(Subscription.class, new Long(id));
    pm.currentTransaction().begin();
    pm.deletePersistent(s);
    pm.currentTransaction().commit();
    pm.flush();

    pm.close();

    return true;
  }
 


  /**
   * Remove subscription
   *
   * @param email
   * @param blogId
   * @return
   */
  public boolean removeUserSubscription(String email, final long blogId) {
   
    email = TextTools.cleanJID(email);
   
    DataManager dm = DataManagerFactory.getInstance();
    PersistenceManager pm = dm.newPersistenceManager();

    Query qUser = pm.newQuery(User.class);
    qUser.setFilter("id == email");
    qUser.declareParameters("String email");
    qUser.setRange(0, 1);
    qUser.setUnique(true);

    User user = (User) qUser.execute(email);

    if (user == null) {
      qUser.closeAll();
      return false;
    }

    Blog blog = pm.getObjectById(Blog.class, new Long(blogId));

    Query q = pm.newQuery(Subscription.class);
    q.setFilter("userKey == uid && blogKey == bid");
    q.declareParameters("com.google.appengine.api.datastore.Key uid, com.google.appengine.api.datastore.Key bid");
    q.setRange(0, 1);

    @SuppressWarnings("unchecked")
    List<Subscription> list = (List<Subscription>) q.execute(user.getKey(),
        blog.getKey());

    if (list.size() > 0) {
      pm.currentTransaction().begin();
      pm.deletePersistent(list.get(0));
      pm.currentTransaction().commit();
      pm.flush();

    }
    q.closeAll();
    pm.close();

    return true;
  }



  /**
   * Find the next entry for current subscription
   *
   * @return
   */
  private BlogEntry findNextEntry(Subscription sub) {
    checkArguments(this.currentManager != null,
        "current PersistenceManager is null");

    // find oldest entry from blog subscription which haven't been sent
    Query q = this.currentManager.newQuery(BlogEntry.class);
    q.setFilter("blogKey == blog && pubDate > date");
    q.setOrdering("pubDate");
    q.declareParameters("com.google.appengine.api.datastore.Key blog, java.util.Date date");
    q.setUnique(true);
    q.setRange(0, 1);

    // find blog entry
    BlogEntry entryToPush = (BlogEntry) q.execute(sub.getBlogKey(),
        sub.getLatestEntryNotifiedDate());

    q.closeAll();

    return entryToPush;
  }

  /**
   * Notify new BlogEntry to user and get new "last blogEntry date" return
   * null if no entry is needed
   *
   * @param pm
   * @param sub
   * @param jabberId
   * @return
   */
  private void sendBlogEntry(JID jabberId, BlogEntry entry) {
    checkArguments(entry != null, "Entry must not be null");

    // fetch link
    String link = entry.getShortLink();

    if (link == null) {
      link = UrlShortenFactory.getInstance().shorten(entry.getLink());
    }

    String blogTitle = entry.getBlogTitle();
    // TODO remove this when production
    if (blogTitle == null)
      blogTitle = this.getBlogTitle(entry);

    // build notification
    JabberBlogNotification notif = new JabberBlogNotification();
    notif.setBlogTitle(blogTitle);
    notif.setJabberID(jabberId);
    notif.setPostTitle(entry.getTitle());
    notif.setPostUrl(link);
    // send notif
    TalkService.sendMessage(notif);

    Logger.getLogger("UserService").info(
        "New entry for " + jabberId.getId() + " : " + link + "["
            + entry.getPubDate() + "]");

  }

  /**
   * To ensure transition
   *
   * @param pm
   * @param be
   * @return
   */
  private String getBlogTitle(BlogEntry be) {
    checkArguments(this.currentManager != null,
        "current PersistenceManager must not be null");
    // TODO remove this

    if (be == null)
      return null;

    Key k = be.getBlogKey();
    String key = "title" + String.valueOf(k.getId());

    Object title = CacheService.get(key);

    if (title == null) {
      Blog b = this.currentManager.getObjectById(Blog.class, k);
      title = b.getTitle();
      if (title != null)
        CacheService.put(key, title);
      else
        return "";
    }

    return title.toString();
  }

 
 
  /**
   *
   * @param expression
   * @param message
   */
  private void checkArguments(boolean expression, String message) {
    if (!expression) {
      throw new IllegalArgumentException(message);
    }
  }

}
TOP

Related Classes of talkfeed.UserManager

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.