package com.tubeonfire.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
import java.util.logging.Logger;
import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheManager;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyOpts;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;
import com.tubeonfire.entity.SpecialTube;
import com.tubeonfire.entity.Tube;
import com.tubeonfire.search.admin.TubeSearchEngine;
public class TubeModel {
private static final Logger log = Logger.getLogger(TubeModel.class
.getName());
private static Objectify ofy;
private static Cache cache = null;
private static boolean isRegisted = false;
private static ObjectifyOpts opts = null;
private static String cacheSide = "frontEnd_";
private static String cachePrefix = "tubeModel_";
private static TreeMap<String, String> mapCacheKey = new TreeMap<String, String>();
private int limit = 30;
private int page = 1;
private int totalResult = 0;
private int totalPage = 1;
private List<Tube> listResult = new ArrayList<Tube>();
public int getTotalPage() {
totalPage = totalResult / limit;
if ((totalResult % limit) > 0) {
totalPage += 1;
}
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getTotalResult() {
return totalResult;
}
public void setTotalResult(int totalResult) {
this.totalResult = totalResult;
}
public List<Tube> getListResult() {
return listResult;
}
public void setListResult(List<Tube> listResult) {
this.listResult = listResult;
}
public static void init() {
if (!isRegisted) {
isRegisted = true;
try {
ObjectifyService.register(Tube.class);
} catch (Exception e) {
isRegisted = false;
}
try {
cache = CacheManager.getInstance().getCacheFactory()
.createCache(Collections.emptyMap());
} catch (CacheException e) {
isRegisted = false;
}
opts = new ObjectifyOpts().setSessionCache(true);
}
ofy = ObjectifyService.begin(opts);
}
public TubeModel() {
init();
}
@SuppressWarnings("unchecked")
public static void update(Tube obj) {
init();
if (cache != null) {
String prefix = cachePrefix + "id_" + obj.getId();
cache.put(prefix, obj);
}
ofy.put(obj);
TubeSearchEngine.update(obj);
clearModelCache();
com.tubeonfire.model.admin.TubeModel.clearModelCache();
com.tubeonfire.search.TubeSearchModel.clearModelCache();
}
@SuppressWarnings("unchecked")
public static Tube getById(String id) {
try {
init();
boolean cached = false;
Tube obj = new Tube();
String prefix = cachePrefix + "id_" + id;
if (cache != null) {
try {
obj = (Tube) cache.get(prefix);
if (obj != null)
cached = true;
} catch (Exception e) {
cached = false;
}
}
if (!cached) {
try {
obj = ofy.get(new Key<Tube>(Tube.class, id));
cache.put(prefix, obj);
} catch (Exception e) {
obj = null;
}
}
return obj;
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
return null;
}
}
@SuppressWarnings("unchecked")
public void prepareTubes() {
try {
listResult = new ArrayList<Tube>();
String prefix = cacheSide + cachePrefix + "tubes_" + page;
mapCacheKey.put(prefix, prefix);
if (cache != null && cache.containsKey(prefix)) {
listResult = (ArrayList<Tube>) cache.get(prefix);
totalResult = (Integer) cache.get("tubesTotalResult");
limit = (Integer) cache.get("tubesLimit");
} else {
int start = (page - 1) * limit;
Query<Tube> q = ofy.query(Tube.class).order("-bumpPoint");
totalResult = q.count();
q = q.limit(limit).offset(start);
for (Tube tub : q) {
listResult.add(tub);
}
if (listResult.size() > 0) {
cache.put(prefix, listResult);
cache.put("tubesTotalResult", totalResult);
cache.put("tubesLimit", limit);
}
}
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
listResult = new ArrayList<Tube>();
}
}
@SuppressWarnings("unchecked")
public void prepareTubeByPlaylist(String playlistId) {
try {
listResult = new ArrayList<Tube>();
String prefix = cacheSide + cachePrefix + "playlist_" + playlistId
+ "_page_" + page;
mapCacheKey.put(prefix, prefix);
String totalResultPrefix = cachePrefix + "playlist_" + playlistId
+ "TotalResult";
String limitPrefix = cachePrefix + "playlist_" + playlistId
+ "Limit";
if (cache != null && cache.containsKey(prefix)) {
listResult = (ArrayList<Tube>) cache.get(prefix);
totalResult = (Integer) cache.get(totalResultPrefix);
limit = (Integer) cache.get(limitPrefix);
} else {
int start = (page - 1) * limit;
Query<Tube> q;
if (cache != null && cache.containsKey(totalResultPrefix)
&& cache.containsKey(limitPrefix)) {
q = ofy.query(Tube.class).filter("playlistId", playlistId)
.order("-bumpPoint").limit(limit).offset(start);
totalResult = (Integer) cache.get(totalResultPrefix);
limit = (Integer) cache.get(limitPrefix);
} else {
q = ofy.query(Tube.class).filter("playlistId", playlistId)
.order("-bumpPoint");
totalResult = q.count();
q = q.limit(limit).offset(start);
}
for (Tube tub : q) {
listResult.add(tub);
}
if (listResult.size() > 0) {
cache.put(prefix, listResult);
cache.put(totalResultPrefix, totalResult);
cache.put(limitPrefix, limit);
}
}
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
listResult = new ArrayList<Tube>();
}
}
@SuppressWarnings("unchecked")
public void prepareTubeByChannel(String channelId) {
try {
listResult = new ArrayList<Tube>();
String prefix = cacheSide + cachePrefix + "channelId_" + channelId
+ "_page_" + page;
mapCacheKey.put(prefix, prefix);
String totalResultPrefix = cachePrefix + "channelId_" + channelId
+ "TotalResult";
String limitPrefix = cachePrefix + "channelId_" + channelId
+ "Limit";
if (cache != null && cache.containsKey(prefix)) {
listResult = (ArrayList<Tube>) cache.get(prefix);
totalResult = (Integer) cache.get(totalResultPrefix);
limit = (Integer) cache.get(limitPrefix);
} else {
int start = (page - 1) * limit;
Query<Tube> q;
if (cache != null && cache.containsKey(totalResultPrefix)
&& cache.containsKey(limitPrefix)) {
q = ofy.query(Tube.class).filter("channelId", channelId)
.order("-bumpPoint").limit(limit).offset(start);
totalResult = (Integer) cache.get(totalResultPrefix);
limit = (Integer) cache.get(limitPrefix);
} else {
q = ofy.query(Tube.class).filter("channelId", channelId)
.order("-bumpPoint");
totalResult = q.count();
q = q.limit(limit).offset(start);
}
for (Tube tub : q) {
listResult.add(tub);
}
if (listResult.size() > 0) {
cache.put(prefix, listResult);
cache.put(totalResultPrefix, totalResult);
cache.put(limitPrefix, limit);
}
}
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
listResult = new ArrayList<Tube>();
}
}
@SuppressWarnings("unchecked")
public void prepareBanner() {
try {
listResult = new ArrayList<Tube>();
String prefix = cacheSide + cachePrefix + "slideshow";
mapCacheKey.put(prefix, prefix);
if (cache != null && cache.containsKey(prefix)) {
listResult = (ArrayList<Tube>) cache.get(prefix);
} else {
SpecialTube spTube = SpecialTubeModel.getByType("slide", true);
if (spTube != null) {
for (String strId : spTube.getListTubeId()) {
listResult.add(getById(strId));
}
}
if (listResult.size() > 0) {
cache.put(prefix, listResult);
}
}
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
listResult = new ArrayList<Tube>();
}
}
@SuppressWarnings("unchecked")
public void prepareLatestTube() {
try {
listResult = new ArrayList<Tube>();
String prefix = cacheSide + cachePrefix + "latest";
mapCacheKey.put(prefix, prefix);
if (cache != null && cache.containsKey(prefix)) {
listResult = (ArrayList<Tube>) cache.get(prefix);
} else {
int start = (page - 1) * limit;
Query<Tube> q = ofy.query(Tube.class).order("-updated")
.limit(limit).offset(start);
for (Tube tub : q) {
listResult.add(tub);
}
if (listResult.size() > 0) {
cache.put(prefix, listResult);
}
}
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
listResult = new ArrayList<Tube>();
}
}
@SuppressWarnings("unchecked")
public void prepareHomePageTubeByPlaylist(String playlistId) {
try {
listResult = new ArrayList<Tube>();
String prefix = cacheSide + cachePrefix + "homepagePlaylist_"
+ playlistId;
mapCacheKey.put(prefix, prefix);
if (cache != null && cache.containsKey(prefix)) {
listResult = (ArrayList<Tube>) cache.get(prefix);
} else {
int start = (page - 1) * limit;
Query<Tube> q = ofy.query(Tube.class)
.filter("playlistId", playlistId).order("-bumpPoint");
totalResult = q.count();
q = q.limit(limit).offset(start);
for (Tube tub : q) {
listResult.add(tub);
}
if (listResult.size() > 0) {
cache.put(prefix, listResult);
}
}
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
listResult = new ArrayList<Tube>();
}
}
@SuppressWarnings("unchecked")
public void prepareHomePageTubeByChannel(String channelId) {
try {
listResult = new ArrayList<Tube>();
String prefix = cacheSide + cachePrefix + "homepageChannel_"
+ channelId;
mapCacheKey.put(prefix, prefix);
if (cache != null && cache.containsKey(prefix)) {
listResult = (ArrayList<Tube>) cache.get(prefix);
} else {
int start = (page - 1) * limit;
Query<Tube> q = ofy.query(Tube.class)
.filter("channelId", channelId).order("-bumpPoint");
totalResult = q.count();
q = q.limit(limit).offset(start);
for (Tube tub : q) {
listResult.add(tub);
}
if (listResult.size() > 0) {
cache.put(prefix, listResult);
}
}
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
listResult = new ArrayList<Tube>();
}
}
@SuppressWarnings("unchecked")
public void prepareRelateTube(Tube obj) {
try {
listResult = new ArrayList<Tube>();
boolean cached = false;
String prefix = cacheSide + cachePrefix + "relate_with_id_"
+ obj.getId();
mapCacheKey.put(prefix, prefix);
String playlistKeyPoolPrefix = "";
playlistKeyPoolPrefix = cachePrefix + "playlistIdPool_"
+ obj.getPlaylistId();
if (cache != null && cache.containsKey(prefix)) {
try {
listResult = (ArrayList<Tube>) cache.get(prefix);
if (listResult != null && listResult.size() > 0)
cached = true;
} catch (Exception e) {
cached = false;
}
}
if (!cached) {
// get pool id by playlist
List<Key<Tube>> keyPool = new ArrayList<Key<Tube>>();
boolean cachedKeyPool = false;
if (cache != null) {
try {
keyPool = (ArrayList<Key<Tube>>) cache
.get(playlistKeyPoolPrefix);
if (keyPool != null && keyPool.size() > 0)
cachedKeyPool = true;
} catch (Exception e) {
cachedKeyPool = false;
}
}
if (!cachedKeyPool) {
keyPool = ofy.query(Tube.class)
.filter("playlistId", obj.getPlaylistId())
.listKeys();
cache.put(playlistKeyPoolPrefix, keyPool);
}
// get list id random from pool
List<Key<Tube>> relateKey = new ArrayList<Key<Tube>>();
if (keyPool.size() > 20) {
Random randomGenerator = new Random();
int index = randomGenerator
.nextInt((int) (keyPool.size() / 2));
relateKey = keyPool.subList(index, (index + 10));
} else if (keyPool.size() < 5) {
relateKey = ofy.query(Tube.class).limit(10).listKeys();
} else {
relateKey = keyPool;
}
// get tube by list key
Map<Key<Tube>, Tube> mapTube = ofy.get(relateKey);
for (Tube tub : mapTube.values()) {
if (!tub.getId().equals(obj.getId())) {
listResult.add(tub);
}
}
if (listResult.size() > 0) {
cache.put(prefix, listResult);
}
}
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
listResult = new ArrayList<Tube>();
}
}
public static void clearModelCache() {
init();
try {
if (mapCacheKey != null && mapCacheKey.size() > 0) {
for (String key : mapCacheKey.keySet()) {
cache.remove(key);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}